Проверка на процесс, ранее запущенный приложением, всегда возвращает процесс живым
Я создаю процесс с 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
}