1

I am creating a process with CreateProcess:

  • with flags CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS
  • InheritHandles param = TRUE
  • startupinfo stdout and stderr file redirection (STARTF_USESTDHANDLES)
  • SECURITY_ATTRIBUTES.InheritHandle = TRUE

The handle the the process is closed while it continues its execution.

Then I am checking the process state by getting the handle for process with given PID:

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

Edit: Yes, I am checking whether the returned process is really the process I queried for:

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

Regardless of whether the created process is really running or not, I am getting a valid handle to the process. If I restart my application, the check code works properly. I suspect that the handle is somehow buffered, or the created process is in the same group - but I can't seem to find any information about it in the documentation.

Dariusz
  • 21,561
  • 9
  • 74
  • 114
  • Are you getting a valid handle to `the` process or a valid handle to `a` process? I thought Windows re-used process identifiers. – ta.speot.is Mar 20 '14 at 08:41
  • It's **the** valid handle. – Dariusz Mar 20 '14 at 08:42
  • And for what it's worth I read [the documentation for OpenProcess](http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx) which has this curiosity from the community: *when a process is not existing, OpenProcess give back a HANDLE to the next lower process pid* – ta.speot.is Mar 20 '14 at 08:42
  • Why don't you wait for the process handle returned by CreateProcess? – Alex F Mar 20 '14 at 08:44
  • @AlexFarber Please elaborate. I am doing other work in the meantime. I don't store the handle. And what you're suggesing between the lines is a workaround, not an answer:) – Dariusz Mar 20 '14 at 08:48
  • I know, but waiting for created process handle is default and straightforward way to know, whether the process is active, and you are using polling. – Alex F Mar 20 '14 at 08:53
  • @AlexFarber if you have a different way of checking, feel free to add it as an answer. – Dariusz Mar 20 '14 at 08:57
  • 1
    It doesn't deserve to be posted as an answer, this is well-known fact: process handled is signaled, when process exits. So, you can use any of Wait functions (like WaitForSingleObject) to know exactly, when the process exits. Your GetExitCodeProcess workaround may fail when the process handle is reused. – Alex F Mar 20 '14 at 09:07
  • @AlexFarber I am getting the process handle just before I check get exit code - how can the handle be reused? How can I use handles at all if they can be switched in the meantime? The only pitfall I can see is the return code. – Dariusz Mar 20 '14 at 09:12
  • Well, I think Windows will not reuse the handle unless you close it, so your workaround is OK for polling. – Alex F Mar 20 '14 at 09:30
  • Do you also close the thread handle in PROCESS_INFORMATION? – manuell Mar 20 '14 at 13:34
  • @manuell yes, I do. The handle is closed after the check. A process handle is also closed after the process is created. – Dariusz Mar 20 '14 at 17:31

2 Answers2

1

There is no guarantee that successfully opening a handle to a process means that the process is still running. So the behaviour you're describing is unsurprising.

Once you've opened a handle, you can easily check whether the process has finished:

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

However, your approach is flawed to begin with, because you have no way of telling whether the process ID has been reused. Instead of storing the process ID, store the process handle returned from CreateProcess, and use it to test for process exit as shown.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
0

While this is not an answer, it does work as a workaround:

Having a valid handle, one can check if the process has finished with:

DWORD exitCode = 0;
GetExitCodeProcess(HProcess, &exitCode);
if (exitCode == STILL_ACTIVE ) {
  //task alive (or exited with STILL_ACTIVE :( )
} else {
  //task exited with code exitCode
}
Dariusz
  • 21,561
  • 9
  • 74
  • 114