C++, How to determine if a Windows Process is running?

前端 未结 13 1072
清酒与你
清酒与你 2020-11-27 15:27

This is concerning Windows XP processes.

I have a process running, let\'s call it Process1. Process1 creates a new process, Process2, and saves its id.

Now,

相关标签:
13条回答
  • 2020-11-27 16:01

    JaredPar is right in that you can't know if the process is running. You can only know if the process was running at the moment you checked. It might have died in the mean time.

    You also have to be aware the PIDs can be recycled pretty quickly. So just because there's a process out there with your PID, it doesn't mean that it's your process.

    Have the processes share a GUID. (Process 1 could generate the GUID and pass it to Process 2 on the command line.) Process 2 should create a named mutex with that GUID. When Process 1 wants to check, it can do a WaitForSingleObject on the mutex with a 0 timeout. If Process 2 is gone, the return code will tell you that the mutex was abandoned, otherwise you'll get a timeout.

    0 讨论(0)
  • 2020-11-27 16:03

    The process handle will be signaled if it exits.

    So the following will work (error handling removed for brevity):

    BOOL IsProcessRunning(DWORD pid)
    {
        HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
        DWORD ret = WaitForSingleObject(process, 0);
        CloseHandle(process);
        return ret == WAIT_TIMEOUT;
    }
    

    Note that process ID's can be recycled - it's better to cache the handle that is returned from the CreateProcess call.

    You can also use the threadpool API's (SetThreadpoolWait on Vista+, RegisterWaitForSingleObject on older platforms) to receive a callback when the process exits.

    EDIT: I missed the "want to do something to the process" part of the original question. You can use this technique if it is ok to have potentially stale data for some small window or if you want to fail an operation without even attempting it. You will still have to handle the case where the action fails because the process has exited.

    0 讨论(0)
  • 2020-11-27 16:03

    You can never check and see if a process is running, you can only check to see if a process was running at some point in the recent past. A process is an entity that is not controlled by your application and can exit at any moment in time. There is no way to guaranteed that a process will not exit in between the check to see if it's running and the corresponding action.

    The best approach is to just do the action required and catch the exception that would be thrown if the process was not running.

    0 讨论(0)
  • 2020-11-27 16:04

    You can use GetExitCodeProcess. It will return STILL_ACTIVE (259) if the process is still running (or if it happened to exit with that exit code :( ).

    0 讨论(0)
  • 2020-11-27 16:06

    Another way of monitoring a child-process is to create a worker thread that will :

    1. call CreateProcess()
    2. call WaitForSingleObject() // the worker thread will now wait till the child-process finishes execution. it's possible to grab the return code (from the main() function) too.
    0 讨论(0)
  • 2020-11-27 16:06

    TL;DR Use GetProcessVersion.

    All of these function are available in Windows XP [desktop apps | UWP apps].

    GetProcessVersion uses a Process ID and returns 0 if the process of the given id is not running.

    GetExitCodeProcess uses a Process handle and gives you the process exit code, if the code is STILL_ACTIVE (259) the process is still running so you could check if it is not STILL_ACTIVE (259) meaning that the process is not running. This is likely to work in basically every situation, unless the process exits with code 259.

    WaitForSingleObject uses a Process handle with the SYNCHRONIZE access right and returns 0 if the process is not running. You should not specify INFINITE for the dwMilliseconds parameter because the function would not return until the process state became signaled(process is terminated).

    0 讨论(0)
提交回复
热议问题