通过pid判断进程是否存在windows

Judging if a process exists by pid windows

我正在开发的功能的最初目标是简单地检查给定特定进程 ID 的 Windows 平台中的进程是否仍然存在(未终止,完全 运行) .但是,我遇到了一个奇怪的情况,即 OpenProcess() 返回 ERROR_ACCESS_DENIED(代码:5),尽管 Process Explorer 上没有显示这样的进程。

所以我进行了搜索,发现了一个类似的问题,其中分享了一些关于我正在寻找的内容的想法。

Can OpenProcess with error code ERROR_ACCESS_DENIED be used to know if process exists?

我能够确定问题所在,但由于解决方案在处理过程的 ERROR_ACCESS_DENIED 方面没有太多亮点。

总之,我从题目中得到了一些想法。这是我目前得到的代码

    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);
    }

使用上面的代码,我能够过滤掉我之前描述的问题。但我只是觉得如果不断调用它,迭代整个进程列表似乎是一个很大的开销。有没有更好的方法来解决这类问题?任何见解将不胜感激。提前致谢。

编辑: 我知道有一种情况 一个进程不是 运行,但它的对象仍然存在 (这种情况可能是调用者没有关闭进程句柄)。我不想计算 process existing 这样的情况,因为它们实际上不是 运行。这就是为什么我对我有访问权限的进程使用 GetExitCodeProcess() 而对我没有访问权限的进程使用 tl32Snapshot 的原因。 我的假设错了吗?

Would there be a better method on approaching this type of problem?

确实如此。

使用 PID 检查进程是否存活不是解决方案 - 所以你应该回去检查你的整体设计。

只需使用进程启动时获得的句柄:

HANDLE hProcess = CreateProcess(...

这听起来好像进程不是从这个进程创建的 - 所以也许像你曾经做过的那样获取它并保留它(即,一旦找到进程就尝试存储句柄而不是继续使用 PID) .

现在您可以使用函数 GetExitCodeProcess ala.:

进行检查
  DWORD returnCode{};
  if (GetExitCodeProcess(handle, &returnCode)) {
    if (returnCode != STILL_ACTIVE) {
      //no longer active

使用 PID 不好的原因有两个:OS 可能会使进程处于 dead 状态一段时间 and 一旦您检查了 PID,它可能已经被新进程重用(在任何正常情况下您根本无法控制它)。

至于ERROR_ACCESS_DENIED:它根本不是一个可靠的方法来检查进程是否存在。