WINSDK: определение того, идентифицирует ли произвольный pid запущенный процесс в Windows - PullRequest
2 голосов
/ 05 марта 2010

Попытка выполнить тест бедняков о том, запущен процесс или нет (по сути, эквивалент тривиального 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 принадлежит другому (не SYSTEM) пользователю. Более того, если pid изначально принадлежал другому пользователю, но с тех пор прекратил работу, OpenProcess также завершится с ERROR_ACCESS_DENIED (не ERROR_INVALID_PARAMETER.)

Нужно ли использовать Process32First / Process32Next или EnumProcesses?

Я абсолютно не хочу использовать SeDebugPrivilege.

Спасибо, V * * 1 032

Ответы [ 2 ]

1 голос
/ 01 февраля 2015

Если у вас есть идентификатор процесса:

// 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;
0 голосов
/ 12 марта 2010
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;
}
...