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

时间:2010-03-05 01:42:47

标签: windows security process winapi

尝试实施一个穷人对流程是否仍在运行的测试(基本上相当于简单的kill(pid, 0)。)

希望只需调用OpenProcess一些最低限度的访问权限,然后测试GetLastError() == ERROR_INVALID_PARAMETERGetExitCodeProcess(...) != STILL_ACTIVE

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

HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!hProc) {
  DWORD dwLastError = GetLastError();
}
dwLastError == ERROR_ACCESS_DENIED由另一个(非SYSTEM)用户拥有时,

...与pid失败。此外,如果pid 最初由其他用户拥有但已终止,OpenProcess也会因ERROR_ACCESS_DENIED(而不是ERROR_INVALID_PARAMETER而失败。)< / p>

我是否必须使用Process32First / Process32NextEnumProcesses

我绝对不想使用SeDebugPrivilege

谢谢, V

2 个答案:

答案 0 :(得分:1)

如果您有进程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;

答案 1 :(得分:0)

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