The original goal of the function that I'm developing was to, simply, check if a process still exists(not terminated, fully running) in Windows platform given a specific process ID. However, I was met with a strange situation where OpenProcess()
was returning ERROR_ACCESS_DENIED
(Code:5) although no such process was showing on the Process Explorer.
So I searched, and found a similar question that shared some ideas on what I was looking for.
Can OpenProcess with error code ERROR_ACCESS_DENIED be used to know if process exists?
I was able to identify the problem, but since the solution did not shine much light on handling ERROR_ACCESS_DENIED
side of the process.
Anyhow, I got some ideas out of the question. And Here's the code I've got so far
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPid);
if( hProcess == NULL )
{
dwLastError = GetLastError();
if( dwLastError == ERROR_ACCESS_DENIED )
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &processEntry))
{
while( Process32Next(hSnap, &processEntry) )
{
if (processEntry.th32ProcessID == dwPid)
{
bAliveProcess = TRUE;
break;
}
}
}
CloseHandle(hSnap);
}
}
else
{
BOOL bExit = GetExitCodeProcess(hProcess, &dwExitCode);
if (dwExitCode == STILL_ACTIVE)
{
bAliveProcess = TRUE;
}
CloseHandle(hProcess);
}
With the code above, I was able to filter out the problem I described earlier. But I just feel like iterating entire process list seems like a big overhead if it gets called constantly. Would there be a better method on approaching this type of problem? Any insights would be appreciated. Thanks in advance.
Edit:
I understand there is a case where a process is not running, but its object still exists (such case may be, a caller did not close the process handle). I did not want to count such cases as process existing since they are not actually running. That's why I used GetExitCodeProcess()
for the processes that I have the access rights and tl32Snapshot
for the process that I don't.
Is my assumption wrong?
Would there be a better method on approaching this type of problem?
Indeed so.
Using PID for checking if process is alive is not a solution - so you should go back and check your overall design.
Just use the handle you get when the process is started:
HANDLE hProcess = CreateProcess(...
It could sound like the process is not created from this process - so perhaps obtain it like you do once, and keep it (ie. try to store the handle once the process is found instead of keep using the PID).
Now you can check using for example the function GetExitCodeProcess
ala.:
DWORD returnCode{};
if (GetExitCodeProcess(handle, &returnCode)) {
if (returnCode != STILL_ACTIVE) {
//no longer active
The reason using PID is bad is twofold: the OS may keep the process in a dead state for a while and the PID may already be reused for a new process once you check it (you simply cannot control that in any normal cases).
As for the ERROR_ACCESS_DENIED
: it's not a reliable method at all to check if the process exists or not.