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, тогда текущий каталог будет как у родительского процесса.