Проверка на процесс, ранее запущенный приложением, всегда возвращает процесс живым

Я создаю процесс с CreateProcess:

  • с флагами CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS
  • InheritHandles param = TRUE
  • Startinfo перенаправление файлов stdout и stderr (STARTF_USESTDHANDLES)
  • SECURITY_ATTRIBUTES.InheritHandle = TRUE

Дескриптор процесса закрыт, пока он продолжает свое выполнение.

Затем я проверяю состояние процесса, получая дескриптор процесса с заданным PID:

HANDLE HProcess = OpenProcess( 
       PROCESS_QUERY_INFORMATION , TRUE, task->taskPid);

Изменить: Да, я проверяю, является ли возвращенный процесс действительно процесс, для которого я запросил:

if ( ( HProcess != NULL ) && ( GetProcessId(HProcess) != requestedPid ) )

Независимо от того, действительно ли созданный процесс запущен или нет, я получаю действительный дескриптор процесса. Если я перезапущу свое приложение, контрольный код работает правильно. Я подозреваю, что дескриптор каким-то образом буферизован, или созданный процесс находится в той же группе - но я не могу найти какую-либо информацию об этом в документации.

2 ответа

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

Открыв дескриптор, вы можете легко проверить, завершился ли процесс:

DWORD dw = WaitForSingleObject(handle, 0);
if (dw == WAIT_OBJECT_0)
{
    // Process has exited
}

Однако ваш подход с самого начала имеет недостатки, так как вы не можете сказать, был ли идентификатор процесса использован повторно. Вместо сохранения идентификатора процесса сохраните дескриптор процесса, возвращенный из CreateProcess, и используйте его для проверки завершения процесса, как показано на рисунке.

Хотя это не ответ, он работает как обходной путь:

Имея действительный дескриптор, можно проверить, завершился ли процесс с:

DWORD exitCode = 0;
GetExitCodeProcess(HProcess, &exitCode);
if (exitCode == STILL_ACTIVE ) {
  //task alive (or exited with STILL_ACTIVE :( )
} else {
  //task exited with code exitCode
}
Другие вопросы по тегам