FAQ:WinAPI VCPP:ожидание завершения процесса
Материал из Весельчак У
Я запускаю экзешник при помощи ::ShellExecute(). Процедура тут же возвращает управление, а как дождаться, когда запущенный процесс завершится, только потом продолжить выполнение программы?
Нужно использовать функции
- CreateProcess()
- WaitForSingeObject()
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
DWORD dwRetValue;
RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
// запуск экзешника
if (!CreateProcess(
szApplicationName,
szCommandLine, // командная строка (можно указать NULL)
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
szCurrentDirectory, // рабочая директория (можно указать NULL)
&StartupInfo,
&ProcessInfo))
{
// ошибка запуска
// определяем ошибку
DWORD dwdErr = GetLastError();
}
else
{
// ждём 30 секунд момента, пока процесс завершится
// (ProcessInfo.hProcess перейдёт в сигнальное состояние)
// если задать INFINITE, будет ждать до бесконечности
DWORD dwd = WaitForSingleObject(ProcessInfo.hProcess, 30000);
// dwd покажет причину завершения процедуры WaitForSingleObject
// WAIT_OBJECT_0 - Состояние объекта переведено в сигнальное
// WAIT_TIMEOUT - Кончился таймаут
// к теме не относится, но для мутекса ещё есть возвращаемое значение:
// WAIT_ABANDONED - Объект является мутексом, который был занят потоком,
// затем поток завершился, не разблокировав мутекс. Мутекс находится
// в несигнальном состоянии
// если нужно - смотрим, какое значение вернуло приложение
GetExitCodeProcess(ProcessInfo.hProcess, &dwRetValue);
// освобождаем хендлы, открытые CreateProcess
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
В szApplicationName может быть либо полный путь к файлу, либо только имя файла. В последнем случае файл будет искаться в текущем каталоге.
szCommandLine может быть NULL, если не надо передавать командную строку запускаемому процессу.
szCurrentDirectory может быть NULL, тогда текущий каталог будет как у родительского процесса.