what's the easiest way to find out if a process which was previously opened is still open?
i.e. i opened the process myself with OpenProcess and I have both the PID and the handle.
How can I test to see if the process has closed?

Also, can you call KillTimer within the timers own callback proc?
For some reason when I do that it doesn't work. Timer continues to run.

I have something like this:




#define TIMER_INTERVAL = 500;
UINT timer = 0;
DWORD pid = 0;



int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
//open process, store pid and handle in global vars
//set a polling timer
timer = SetTimer(NULL, TIMER_INTERVAL, TIMER_INTERVAL, timerProc);
.......
}


void CALLBACK timerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime )
{
if(!OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid))
{

MessageBox(NULL, "Command & Conquer no longer running. Please
run Command & Conquer and then try again.", "Error", MB_OK | MB_SYSTEMMODAL | MB_ICONWARNING);
DestroyWindow ((HWND)TheInstance);
KillTimer(NULL, timer);
return;
}
if(!moneyActive && !powerActive) KillTimer(NULL, timer);
if(moneyActive) pokeMoney();
if(powerActive) pokePower();
}
Posted on 2004-07-28 01:43:15 by
GetExitCodeProcess is the API for that. To have your program wait for the process to end use WaitForSingleObject using the process handle.
Posted on 2004-07-28 03:05:10 by donkey
Do a single OpenProcess call at the start of you app (paired with a CloseHandle once you no longer need to poke arond in the process).

Then there's two ways to handle the check for process termination. WaitForSingleObject is good if you just want to wait for process termination and use the least possible resources while doing so.

However, considering the structure of your program (and that you're going to check with 500ms intervals and not do constant polling), it's probably smartest to call GetExitCodeProcess and check for STILL_ACTIVE.

The handle you get with OpenProcess will, by the way, *not* become invalid when the process terminates. Windows will keep the kernel-mode object in memory until the process is terminated and all handles are closed - which is why you should always remember to call CloseHandle.
Posted on 2004-07-28 08:27:55 by f0dder
Thanks. GetExitCodeProcess and check for STILL_ACTIVE works great.
Posted on 2004-07-28 16:48:19 by
ehrm..I am a bit off topic here with my question but could it be possible in my own program which is running at ring 3 level to check if it was opened by some other process using OpenProcess ?
Posted on 2004-08-03 04:35:31 by DZA
Yes,

You can use my system.lib library and use the function GetParentPID9x or GetParentPIDNT to get the name and PID of the process that opened yours.
Posted on 2004-08-03 07:24:49 by donkey
really nice code donkey :) thanks
Posted on 2004-08-04 03:17:56 by DZA

Thanks. GetExitCodeProcess and check for STILL_ACTIVE works great.


Just a side note, it's not a bulletproof method. If the process happens to return the value of STILL_ACTIVE in ExitProcess, your code won't detect it. :(

As an alternative (but it's some more work) you could create another thread, which will call WaitForSingleObject to wait for the process to finish, and then send a message to your main window using SendMessage.

Come to think of it, tf you also need to be able to quit while waiting, then WaitForMultipleObjects would be better. Create an event object and make your secondary thread wait for both the process and the event. :)
Posted on 2004-08-04 13:24:53 by QvasiModo