Запустите программу Windows и определите, когда она заканчивается на C ++ - PullRequest
3 голосов
/ 04 декабря 2009

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

Ответы [ 7 ]

9 голосов
/ 04 декабря 2009

Это цитата из здесь :

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>

void _tmain( int argc, TCHAR *argv[] )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
STARTUPINFO sj;
PROCESS_INFORMATION pj;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

ZeroMemory( &sj, sizeof(sj) );
sj.cb = sizeof(sj);
ZeroMemory( &pj, sizeof(pj) );

// Start the child process p1.exe. Make sure p1.exe is in the
// same folder as current application. Otherwise write the full path in first argument.
if(!CreateProcess(L".\\p1.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &sj, &pj))
{
printf( "Hello CreateProcess failed (%d)\n", GetLastError() );
getch();
return;
}

// Start child process p2.exe. Make sure p2.exe is in the
// same folder as current application. Otherwise write the full path in first argument.
if(!CreateProcess(L".\\p2.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
printf( "CreateProcess2 failed (%d)\n", GetLastError() );
getch();
return;
}

// Wait until child processes exit.
WaitForSingleObject( pi.hProcess, INFINITE );
WaitForSingleObject( pj.hProcess, INFINITE );

// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
CloseHandle( pj.hProcess );
CloseHandle( pj.hThread );
getch();
}
2 голосов
/ 04 декабря 2009

CreateProcess и WaitForSingleObject - это простой способ добиться этого: вы получаете дескриптор процесса из CreateProcess, затем ждете его с помощью WFSO, не забывая закрывать любые используемые вами дескрипторы. Но подождите ... есть проблема. Проблема в том, что - для процессов с графическим интерфейсом - оба процесса могут зависать. Почему?

Проблема возникает из-за того, что у вашего приложения есть окно, но оно не перекачивает сообщения. Если порожденное приложение вызывает SendMessage с одной из целей широковещания (HWND_BROADCAST или HWND_TOPMOST), то SendMessage не вернется в новое приложение, пока все приложения не обработают сообщение - но ваше приложение не может обработать сообщение потому что он не качает сообщения .... поэтому новое приложение блокируется, поэтому ваше ожидание никогда не будет успешным .... DEADLOCK.

Если у вас есть абсолютный контроль над порожденным приложением, то вы можете принять меры, такие как использование SendMessageTimeout, а не SendMessage (например, для инициализации DDE, если кто-то еще использует это). Но есть ситуации, которые вызывают неявные широковещательные рассылки SendMessage, над которыми у вас нет контроля, например, используя API-интерфейс SetSysColors.

Единственные безопасные способы обойти это: (а) разделить ожидание на отдельный поток, (б) использовать тайм-аут на ожидании и использовать PeekMessage в цикле ожидания, чтобы гарантировать, что вы перекачиваете сообщения, (в) использовать API MsgWaitForMultipleObjects вместо WaitForSingleObject.

1 голос
/ 24 июня 2015

Я хотел бы отметить, что вам не нужно создавать процесс, чтобы иметь возможность ждать его завершения. По сути, если вы знаете его PID, вы можете сделать это:

 HANDLE h = OpenProcess(SYNCHRONIZE, TRUE, pid);
 WaitForSingleObject(h, INFINITE );

Полный пример: https://gist.github.com/rdp/6b5fc8993089ee12b44d (оставьте комментарий здесь, если вы хотите, чтобы скомпилированная версия была доступна).

1 голос
/ 04 декабря 2009

Альтернативный подход, который предлагает еще больший контроль, заключается в использовании Win32 Job API, см. CreateJobObject () и AssignProcessToJobObject () . Это позволит вам асинхронно отслеживать порожденный процесс с помощью порта завершения ввода-вывода с помощью SetInformationJobObject () это более сложный и, вероятно, больше, чем нужно, но дает гораздо больший контроль над порожденными процессами.

1 голос
/ 04 декабря 2009

В Windows вы можете использовать WaitForSingleObject для реализации этой функции.

0 голосов
/ 22 марта 2016

По крайней мере, в Windows есть некоторые (недостаточно используемые?) Функциональные возможности библиотеки времени выполнения C, доступные для этого. См. Process and Environment Control"> C Справочник библиотеки времени выполнения> Управление процессом и средой .

В частности, у вас есть _spawnlp (_P_WAIT, cmdname, arg0, ..., argn, 0) (" spawn с аргументом l ist, используя переменную p ath для поиска файла ") который ищет cmdname в PATH и в текущем каталоге. Обратите внимание: «После argn должен быть указатель NULL, чтобы отметить конец списка аргументов».

* 1016 Е.Г. *

#include <stdio.h>
#include <process.h>
int main() {
    puts("waiting");
    _spawnlp(_P_WAIT, "mspaint.exe", "mspaint.exe", 0);
    puts("returned");
}
0 голосов
/ 04 декабря 2009

В быстром поиске в Google я нашел два метода из msdn, которые могут быть полезны:

CreateProcess и GetExitCodeProcess . Это при условии, что вы создаете процесс в своем приложении.

Вы можете сделать опрос методом проверки статуса созданного процесса. Я никогда такого не делал, но мне кажется очень странным подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...