代码之家  ›  专栏  ›  技术社区  ›  vladr

winsdk:确定任意pid是否标识windows上正在运行的进程

  •  2
  • vladr  · 技术社区  · 15 年前

    试图实现穷人对进程是否仍在运行的测试(本质上相当于 kill(pid, 0) )

    希望能简单的打电话 OpenProcess 使用一些最小的期望访问,然后测试 GetLastError() == ERROR_INVALID_PARAMETER GetExitCodeProcess(...) != STILL_ACTIVE

    很好的尝试…以管理员身份在Windows XP上运行:

    HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (!hProc) {
      DWORD dwLastError = GetLastError();
    }
    

    …惨败于 dwLastError == ERROR_ACCESS_DENIED 什么时候 pid 属于其他(非系统)用户。此外,如果 PID 最初由不同用户拥有,但后来终止, 开放过程 也会失败 ERROR_ACCESS_DENIED (不是) ERROR_INVALID_PARAMETER )

    我要用吗 Process32First / Process32Next EnumProcesses ?

    我绝对 不想使用 SeDebugPrivilege .

    谢谢, V

    2 回复  |  直到 10 年前
        1
  •  1
  •   George Valkov    10 年前

    如果您有进程ID:

    // this should succeed even when a medium integrity process
    // requests access to a high integrity process
    if (HANDLE h = OpenProcess(SYNCHRONIZE, FALSE, pid))
    {
        // do a wait, if the handle is signaled: not running
        DWORD wait = WaitForSingleObject(h, 0);
        if (wait == WAIT_OBJECT_0) return FALSE;
    }
    // cannot get a handle to the process:
    // probably running at system integrity level
    // I'm not sure how reliable this check is, but it seems to work:
    // if access is denied: running
    // if invalid parameter: not running
    else if (GetLastError() != ERROR_ACCESS_DENIED) return FALSE;
    

    如果您有一个窗口句柄,只要进程在运行,它就应该是有效的,这是一个很好的选择:

    if (hWnd && !IsWindow(hWnd)) return FALSE;
    
        2
  •  0
  •   vladr    13 年前
    static BOOL
    isProcessAlive(DWORD th32ProcessID) {
      BOOL bSuccess = FALSE;
    
      HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      if (hSnap != INVALID_HANDLE_VALUE) {
        PROCESSENTRY32 pe32 = { sizeof(pe32), 0 };
        if (Process32First(hSnap, &pe32)) {
          while (pe32.th32ProcessID != pid && Process32Next(hSnap, &pe32));
          _ASSERT(GetLastError() == 0 || GetLastError() == ERROR_NO_MORE_FILES);
          bSuccess = (pe32.th32ProcessID == th32ProcessID);
        }
        CloseHandle(hSnap);
      }
      return bSuccess;
    }