Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/35: Рейтинг темы: голосов - 35, средняя оценка - 4.94
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020

Закрытие процесса

11.08.2015, 16:35. Показов 7176. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
У меня есть такой код:
C++
1
2
3
4
5
6
if (CreateProcess(directory.c_str(), cmd, NULL, NULL, true, NORMAL_PRIORITY_CLASS, NULL, NULL, &cif, &pi ))
                    {                   
                                                   
                            OpenProcess(PROCESS_TERMINATE, false,pi.dwProcessId );
                            CloseHandle(pi.hProcess);                       
                    }
Утилита множество раз обращается к нему, из-за этого создается много процессов, они отрабатывают, но не завершаются сразу, кроме того появляются процессы cmd.exe, которые также висят не подавая признаков жизни.
Что я делаю не так ? Как бороться с cmd.exe и conhost.exe ?

Добавлено через 10 минут
Как узнать существует ли процесс по PID ?

Добавлено через 12 минут
Что возвращает OpenProcess, когда вызывается с PROCESS_TERMINATE?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.08.2015, 16:35
Ответы с готовыми решениями:

Активация и закрытие запущенного процесса
Вопрос, скорее всего простой, но вот никак не могу найти нужную АПИ-функцию. Я создаю процесс CreateProcess-ом. Этот процесс - оконный....

при создании процесса создаётся ярлык в трее, по окончании процесса он не убираетс сам, как его убрать оттуда?
Друзья! Вот исходник процесса, качнул с инета. Это в консольном режиме запускат аудио файлы, например mp3: // cmdmp3 // A command-line...

Как узнать id процесса по имени процесса?
Как узнать id процесса по имени процесса? Например ищем notepad.exe и возвращается id этого процесса. Пол гугла обшарил.

22
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18267 / 14190 / 5368
Регистрация: 17.03.2014
Сообщений: 28,879
Записей в блоге: 1
11.08.2015, 18:59
VoltDeMar, начать следует с разбирательства почему процессы не завершаются. Если это слишком долгая команда, это одно. Если ты запускаешь cmd без ключа /c чтобы он автоматически завершился это другое. В приведенном тобой коде вызов OpenProcess является лишним т.к. у тебя уже есть дексприптор процесса в pi.hProcess, плюс ты игнорируешь возвращаемое значение.

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Как узнать существует ли процесс по PID ?
Это плохая идея т.к. под этим PID уже может работать совершенно другой процесс. То есть твой процесс завершился, был запущен другой и ОС назначила ему тот же PID. Можно использовать GetExitCodeProcess для проверки завершилось ли приложение.

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Что возвращает OpenProcess, когда вызывается с PROCESS_TERMINATE?
Дескриптор процесса, о чем ясно сказано в документации.
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
12.08.2015, 08:53  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Дескриптор процесса, о чем ясно сказано в документации.
handler который он возвращает отличается от того который был выдан при создании процесса.

Цитата Сообщение от OwenGlendower Посмотреть сообщение
Если ты запускаешь cmd без ключа /c чтобы он автоматически завершился это другое.
Я не запускаю cmd оно само, так же как и conhost.exe.

Цитата Сообщение от OwenGlendower Посмотреть сообщение
OpenProcess является лишним т.к. у тебя уже есть дексприптор процесса
Я думал что такая команда завершает процесс, так?

Добавлено через 38 секунд
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Можно использовать GetExitCodeProcess для проверки завершилось ли приложение.
Очевидно что приложения у меня не завершаются, как это может помочь?

Добавлено через 37 секунд
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Это плохая идея т.к. под этим PID уже может работать совершенно другой процесс.
Могу проверять имя приложения по PID ?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
12.08.2015, 09:14
Цитата Сообщение от VoltDeMar Посмотреть сообщение
handler который он возвращает отличается от того который был выдан при создании процесса.
Handle - это типа ссылки на объект.
На один и тот же объект может существовать две и более ссылок.
В данном случае оба хэндла ссылаются на один и тот же процесс, только
первый был получен на CreateProcess, а второй на OpenProcess.

Вот тут советую почитать:

Преодолевая ограничения Windows: дескрипторы
http://blogs.technet.com/b/mar... 88042.aspx

"Внутреннее устройство Windows, 6-1" (М. Руссинович, Д. Соломон)
См. "Диспетчер объектов / Дескрипторы объекта и таблица дескрипторов процесса"

Handles and Objects
https://msdn.microsoft.com/en-... 85%29.aspx

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Я думал что такая команда завершает процесс, так?
Процесс не завершается, когда все хэндлы на него закрыты.
Для завершения есть функции ExitProcess и TerminateProcess.

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Очевидно что приложения у меня не завершаются, как это может помочь?
Обычно в дочерний процесс посылают какой-нибудь сигнал (например, взводят win32 event),
означающий, что пришла пора завершать работу, а затем ждут, когда это произойдет.
У хэндлов процессов и потоков есть полезное свойство - они переходят в сигнальное состояние,
когда соответствующий объект ядра (т.е. объект "процесс" или "поток") уничтожается, и
на них можно ждать:
C++
1
2
SetEvent(hQuitEvent); // Отправили сигнал завершения в дочерний процесс.
WaitForSingleObject(hChildProcess, INFINITE); // Ждем, пока он не завершится.
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
13.08.2015, 09:35  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
win32 event
Где бы по подробнее узнать что такое этот event?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.08.2015, 09:49
Event Objects
https://msdn.microsoft.com/en-... 85%29.aspx
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
13.08.2015, 10:54  [ТС]
Если event существует вызывать ExitProcess или Event-ы позволяют какой то ещё функционал?

Есть ли возможность влияния операций в процесс (Например, передать ExitProcess процессу из другого процесса, чтобы он выполнил это от себя)?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.08.2015, 11:37
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Если event существует вызывать ExitProcess или Event-ы позволяют какой то ещё функционал?
Event - это способ нескольких потоков или процессов просигналить
друг другу о том, что некое событие произошло.

Например, поток Consumer ждет события "DataReady" (WaitForSingleObject).
Поток Producer выполняет подготовку данных, а затем взводит событие (SetEvent).
Consumer просыпается, забирает данные и делает свою часть работы.
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
13.08.2015, 11:47  [ТС]
Какой самый быстрый способ вызвать ExitProcess?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.08.2015, 11:55
Родительский процесс создает event в несигнальном состоянии.
Затем запускает дочерний процесс.
Дочерний процесс открывает этот же event (по имени, например) и
устанавливает ожидание (в отдельном потоке или через registered wait).
Когда родитель хочет, чтобы дочерний процесс завершился, он взводит event.
В дочернем завершается ожидание, всем потокам рассылаются соответствующие
уведомления, если нужно, после чего один из них делает ExitProcess.

Это, так сказать, грамотная схема, где все ресурсы будут аккуратно закрыты и
потоки завершат управление в известных и безопасных точках.

Можно сделать грубее - просто TerminateProcess и все
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
13.08.2015, 12:08  [ТС]
ExitProcess требует EXitCode, GetExitCodeProcess() требует хендл, чтобы получить хендл нужно тоже вызвать что то... Как сделать эту цепочку минимально короткой?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.08.2015, 12:13
Цитата Сообщение от VoltDeMar Посмотреть сообщение
ExitProcess требует EXitCode
ExitProcess(0) - в чем проблема ?

Цитата Сообщение от VoltDeMar Посмотреть сообщение
GetExitCodeProcess() требует хендл
У вас он уже есть после вызова CreateProcess или OpenProcess.
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
13.08.2015, 12:31  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Дочерний процесс открывает этот же event (по имени, например) и
устанавливает ожидание (в отдельном потоке или через registered wait).
Когда родитель хочет, чтобы дочерний процесс завершился, он взводит event.
Можно пример?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.08.2015, 12:56
parent:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <Windows.h>
#include <cstdio>
#include <iostream>
 
 
 
int main()
{
    STARTUPINFOW si;
    GetStartupInfoW(&si);
    wchar_t CmdLine[] = L"child.exe";
    PROCESS_INFORMATION pi;
 
    HANDLE const hQuitEvent = CreateEventW(
        NULL, // Security attributs.
        TRUE, // Manual reset or not.
        FALSE, // Initial state.
        L"Local\\ChildQuitEvent"
        );
    if (!hQuitEvent) {
        printf("[ERROR] CreateEventW failed with last error 0x%.8lx.\r\n", GetLastError());
        return EXIT_FAILURE;
    }    
 
    if (!CreateProcessW(
        NULL, // App name.
        CmdLine,
        NULL, // Process security attributes.
        NULL, // Thread security attributes.
        FALSE, // Inherit handles or not.
        NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
        NULL, // Environment.
        NULL, // Current directory.
        &si,
        &pi
        ))
    {
        printf("[ERROR] : CreateProcessW failed with last error 0x%.8lx.\r\n", GetLastError());
        CloseHandle(hQuitEvent);
        return EXIT_FAILURE;
    }
 
    CloseHandle(pi.hThread); // Not needed.
   
    printf(
        "Select option:\r\n"
        "1) Send 'quit' event to the child (soft exit).\r\n"
        "2) Terminate child process (hard exit).\r\n"
        );
 
    int Option = 0;
    std::cin >> Option;
 
    switch (Option)
    {
        case 1:
            SetEvent(hQuitEvent);
            WaitForSingleObject(pi.hProcess, INFINITE);
            break;
 
        case 2:
            TerminateProcess(pi.hProcess, EXIT_FAILURE);
            break;
 
        default:
            printf("Unknown option %d.\r\n", Option);
    }
 
    CloseHandle(pi.hProcess);
    CloseHandle(hQuitEvent);
    return EXIT_SUCCESS;
}
child:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <Windows.h>
#include <cstdio>
 
 
 
int main()
{
    HANDLE const hQuitEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Local\\ChildQuitEvent");
    if (!hQuitEvent) {
        printf("[ERROR] : OpenEventW failed with last error 0x%.8lx.\r\n", GetLastError());
        return EXIT_FAILURE;
    }
 
    WaitForSingleObject(hQuitEvent, INFINITE);
    printf("Exiting...\r\n");
    Sleep(2000);
    CloseHandle(hQuitEvent);
 
    return EXIT_SUCCESS;
}
2
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
17.08.2015, 12:16  [ТС]
А как мне проверить что процесс завершился? Может ли процесс выполнять заданное действие последним, после команды exit(mainret) (например удалить event, только в случае если процесс полностью завершен)?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
17.08.2015, 13:22
Цитата Сообщение от VoltDeMar Посмотреть сообщение
А как мне проверить что процесс завершился?
Хэндл процесса перейдет в сигнальное состояние, т.е. ожидание на хэндле
процесса wait-функцией (например, WaitForSingleObject) будет возвращать
управление с соответствующим кодом.
Либо можно проверять значение GetExitCodeProcess.

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Может ли процесс выполнять заданное действие последним, после команды exit(mainret) (например удалить event, только в случае если процесс полностью завершен)?
Не понял вопроса.
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18031 / 7734 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
17.08.2015, 13:42
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Как бороться с cmd.exe и conhost.exe ?
Заодно объясню Процесс conhost.exe - что это и для чего он запущен?
1
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
20.08.2015, 09:51  [ТС]
Эти эвенты относятся к тем событиям которые можно посмотреть через "Просмотр событий"? Если так то какого они типа, если нет - можно ли их просматривать ? У меня подозрение что WaitForSingleObject не ждет или эвент сразу во взведенном состоянии.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
20.08.2015, 10:00
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Эти эвенты относятся к тем событиям которые можно посмотреть через "Просмотр событий"?
Нет, это две совершенно разные вещи.
0
 Аватар для VoltDeMar
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
20.08.2015, 12:07  [ТС]
У меня появляется ошибка доступа при выполнении приложения, если не ошибаюсь на строке создания Eventa, причем после того как несколько раз эта строка уже исполнялась по логике кода, на одном месте при копировании ярлыка.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
int  CopyCatalog(std::wstring const & Spath, std::wstring const & Dpath, wchar_t StartPath[] , SECURITY_ATTRIBUTES sa)
{      
    int countO = 0; 
    try 
    {       
        std::wstring const searchMask = Spath + L"\\*.*";    // 
        WIN32_FIND_DATA FindFileData;                         
        HANDLE hf = FindFirstFile(searchMask.c_str(), &FindFileData);   // поиск первого файла 
            
        if (hf != INVALID_HANDLE_VALUE)
        { do
            {  if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // если находим дирректорию 
                {   std::wcout << "Directory : " << FindFileData.cFileName << " was skiped." << std::endl;
                    if ((std::wstring)FindFileData.cFileName != L"."  &&  (std::wstring)FindFileData.cFileName != L"..")
                    {   std::wstring dd(Dpath);
                        dd = dd + L"\\" + (std::wstring)FindFileData.cFileName;
                        CreateDirectory(dd.c_str(), &sa );
                        std::wstring sd(Spath);
                        sd = sd + L"\\" + (std::wstring)FindFileData.cFileName;
                        CopyCatalog(sd, dd, StartPath, sa);
                    }
            }
                else
                { 
                    std::wstring directory;
                    std::wstring path = StartPath;
                    const size_t last_slash_idx = path.rfind('\\');
                    if (std::string::npos != last_slash_idx)
                    {   directory = path.substr(0, last_slash_idx); }
                    
                    PROCESS_INFORMATION pi; 
                    STARTUPINFO cif;
                    ZeroMemory(&cif,sizeof(STARTUPINFO));
                    WCHAR cmd[128];
 
                    directory += L"\\CopyFile.exe";
                    std::wstring name(Spath);
                    name = L"\"" + name + L"\\" + FindFileData.cFileName + L"\"  \"" + Dpath.c_str() +  L"\\" + FindFileData.cFileName + L"\"" ;
                    lstrcpy(cmd,  name.c_str());
                    
                    countO ++;
                    int counter = 0;
                      HANDLE h = CreateEventEx(&sa, L"CopyEvent" + countO, CREATE_EVENT_INITIAL_SET, READ_CONTROL );
                    
                      if (CreateProcess(directory.c_str(), cmd, NULL,   NULL, true, NORMAL_PRIORITY_CLASS, NULL, NULL, &cif, &pi ))
                    {         WaitForSingleObject(h,INFINITE);                         
                            DWORD ExitCode;
                            GetExitCodeProcess(h,&ExitCode);
                            if (STILL_ACTIVE != ExitCode )
                            {
                                std::cout << " Still active : " << FindFileData.cFileName << std::endl;
                            }
                            else
                            {
                                 CloseHandle(h);
                                 std::cout << " Process CopyFile closed.  " << FindFileData.cFileName << std::endl;
                            }   }   }   } 
            while (FindNextFile(hf, &FindFileData) != NULL); // ищем следующий файл 
        }
        else
        {   std::cout << "No files in folder. " << std::endl;   }       
        return 0;   }
    catch(...)
    {   std::cout << "Coping unsuccessful." << std::endl;
        return -1;  }}
Миниатюры
Закрытие процесса   Закрытие процесса  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.08.2015, 12:07
Помогаю со студенческими работами здесь

Закрытие процесса
Привет друзья, вообщем морочу себе голову. Немогу понять как правильно в бесконечном цикле сделать закрытие процесса. К примеру,...

Закрытие процесса Word
Здравствуйте форумчане. Написал я метод, извлекающий информацию из документа ворд в строку. Вот, собственно он: private static string...

Закрытие процесса по PID
Здравствуйте! Мне нужно закрыть процесс по его pid просто по имени не катит. Сейчас я закрываю так : Вот такой батник. tasklist /fi...

Закрытие процесса Excel
Здравствуйте. Такая проблемка... У меня в работе берутся данные из файла Excel и заносятся в Stringgrid1. И в принципе все работает,...

Программное закрытие процесса
Господа Программисты Можно ли программно закрыть выполняющийся процесс, как через диспетчер задач. Например, моему приложению...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru