Судя, существует ли процесс по окнам pid - PullRequest
2 голосов
/ 01 октября 2019

Первоначальная цель функции, которую я разрабатываю, состояла в том, чтобы просто проверить, существует ли еще процесс (не завершен, полностью запущен) на платформе Windows с заданным идентификатором процесса. Однако я столкнулся со странной ситуацией, когда OpenProcess() возвращал ERROR_ACCESS_DENIED (код: 5), хотя такой процесс не отображался в Process Explorer.

Так что я искал и нашел похожий вопрос, которыйподелился некоторыми идеями о том, что я искал.

Можно ли использовать OpenProcess с кодом ошибки ERROR_ACCESS_DENIED, чтобы узнать, существует ли процесс?

Мне удалось определить проблему, но, поскольку решение не пролило много света наобработка 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);
    }

С кодом выше я смог отфильтровать проблему, которую я описал ранее. Но я просто чувствую, что итерация всего списка процессов кажется большой нагрузкой, если он вызывается постоянно. Будет ли лучший метод для решения этого типа проблемы? Любые идеи будут оценены. Заранее спасибо.

Редактировать: Я понимаю, что есть случай, когда процесс не запущен, но его объект все еще существует (например, вызывающийне закрывал дескриптор процесса). Я не хотел считать такие случаи как процесс существующим , поскольку они на самом деле не запущены. Вот почему я использовал GetExitCodeProcess() для процессов, для которых у меня есть права доступа, и tl32Snapshot для процесса, которого у меня нет. Мое предположение неверно?

1 Ответ

1 голос
/ 01 октября 2019

Будет ли лучший метод для решения этого типа проблемы?

Действительно, так.

Использование PID для проверки, если процесс жив, нерешение - поэтому вы должны вернуться и проверить свой общий дизайн.

Просто используйте ручку, которую вы получаете, когда процесс начинается:

HANDLE hProcess = CreateProcess(...

Может показаться, что процесс не создан из этого процесса - поэтому, возможно, получите его, как вы, один раз, и сохраните его (т.е. попробуйте сохранить дескриптор, как только процесс будет найден, вместо того, чтобы продолжать использовать PID).

Теперь вы можете проверить, используя, например, функцию GetExitCodeProcess ala.:

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

Причина, по которой использование PID плохая, двояка: ОС может сохранить процесс в dead на некоторое время укажите и , что PID может быть повторно использован для нового процесса после того, как вы проверите его (вы просто не можете контролировать это в любых обычных случаях).

Что касается ERROR_ACCESS_DENIED:это не надежный метод вообще , чтобы проверить, существует ли процессили нет.

...