We help IT Professionals succeed at work.

Waiting for process to terminate - WaitForSingleObject()

The Master
The Master asked
on
I've got an app A that launches a second app B and immediately terminates.  I would like app B to wait on process A to finish before doing any work.  In process B I'm currently calling GetWindowThreadProcessId() to retrieve the process id of A, then using OpenProcess() to obtain the process handle, and then calling WaitForSingleObject() to wait until the process has ended.  The problem is that WaitForSingleObject() is returning WAIT_FAILED.  What am I doing wrong?

Here is how I start the process:

STARTUPINFO si;
memset (&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_FORCEOFFFEEDBACK;

PROCESS_INFORMATION pi;

bResult = CreateProcess (NULL,
                strCmdLine,
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_PROCESS_GROUP,
                NULL,
                NULL,
                &si,
                &pi);

And here is how I attempt to wait on the process in app B:

HWND hwnd = FindWindow (WINDOW_CLASS, WINDOW_NAME);
if (hwnd)
{
     GetWindowThreadProcessId (hwnd, &nProcId);
     HANDLE hProcess = OpenProcess (STANDARD_RIGHTS_REQUIRED, FALSE, nProcId);
     if (hProcess)
     {
          DWORD dwWaitResult = WaitForSingleObject (hProcess, 5000);
     }
}

Thanks for any help!
Comment
Watch Question

jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Why don't you simply provide the parent's process ID on the command line and call 'OpenProcess()' on that ID in the child app? This would enable you to just use 'WaitForSingleObject()' on the process handle without having to use 'FindWindow()'...

Author

Commented:
That was my first attempt, with GetCurrentProcessId() used in process 'A'.  Either way, WaitForSingleObject() returns WAIT_FAILED.

Something else that seems strange is that the error string that matches the code from GetLastError() is "Cannot create a file when that file already exists."  I've even called SetLastError(0) before the wait, just to verify that WaitForSingleObject() is indeed setting it.
What you can do is:
1. In app A create named event in a reset mode - CreateEvent(NULL,FALSE,FALSE,"BTerminated");
2. Run Proccess B from app A and call WaitForSingleObject on the event handle.
3. At the begining of app B call CreateEvent wit the same name of the event created in app A - CreateEvent(NULL,FALSE,FALSE,"BTerminated");
4. When app B is terminating, set the event to signaled.

--EC--
For NT/2000 you must specify SYNCHRONIZE flag in
OpenProcess for enable using the process handle in any of the wait functions to wait for the process to terminate.

OpenProcess(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE, ...

Author

Commented:
SChertkov:

Sorry, you misunderstand.  What I want is for app 'B' to wait until app 'A' terminates.  Not the other way around.

Author

Commented:
Oops, sorry.  That last post was directed at elcapitan.

Thanks Schertkov - that's what I was looking for!  I saw that in the documentation, but I swear I've used WaitForSingleObject with OpenProcess before on Win2k without needing the SYNCHRONIZE flag.  Oh well, adding it worked.

Thanks again!
It doesn't metter if app A waits for app B or the other way around. The thing is that you can use the same event in totally different processes, and wait for one process to signal the other.

--EC--