Ошибка OpenProcess 87 недопустимый параметр

Я пытаюсь написать программу, которая выполняет make.exe из дистрибутива MinGW в текущем каталоге и использует его данные STDOUT и код выхода. У меня есть дескриптор для обработки STDOUT, откуда я беру данные, созданный с помощью CreatePipe. Когда я получаю ERROR_HANDLE_EOF на этом канале, я предполагаю, что процесс завершился, и пытаюсь получить его код выхода:

if(session->pid == 0) return;
HANDLE hp = OpenProcess(PROCESS_QUERY_INFORMATION |
            PROCESS_TERMINATE, TRUE, session->pid);
if(hp == NULL) {
    printf("OpenProcess(%i) failed, error: %i\n",
        session->pid, (int)GetLastError());
    return;
}

Мой код работает со всеми другими утилитами MinGW, которые я тестировал (например, pwd, ls и т. Д.), Я без проблем получаю STDOUT и код выхода. Но когда я пробую это сделать, в приведенном выше коде отображается следующее сообщение:

«OpenProcess (2032) не удалось, ошибка: 87»

Я поискал в Google код ошибки 87, и там написано: «Недопустимый параметр». Я не понимаю, что может быть недействительным в положительном идентификаторе процесса, таком как 2032. Есть идеи?


person user389419    schedule 14.02.2011    source источник


Ответы (3)


Вы должны использовать дескриптор из CreateProcess вместо использования OpenProcess в PID.

OpenProcess работает, только если объект процесса все еще существует. К тому времени, когда вы вызовете OpenProcess, если объект процесса исчез - результатом будет вызов с недопустимым параметром.

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

person John    schedule 14.02.2011

Оставить чаевые для чужих целей. Мне удалось добраться до ERROR_INVALID_PARAMETER (87), попытавшись открыть:

  • Системный процесс (0)
  • идентификатор, который принадлежал теме, а не процессу (ссылка на сообщение YatoDev ).

Второй случай может стать проблемой, если вы, например, запросить результат напрямую от GetWindowThreadProcessId , который является identifier of the thread that created the window вместо параметра указателя (который дает вам запрошенный PID).

person Jon    schedule 16.06.2020

Хотя сообщение старое: я заметил, что получил ERROR_INVALID_PARAMETER, когда процесс существовал, но принадлежал другому пользователю и / или рабочему столу Windows и / или сеансу терминального сервера.

Как ни странно, функция WTSEnumerateProcess() не страдает от этой ошибки, но стоит намного дороже, особенно в системе, которая уже находится под большой нагрузкой со многими процессами (и вызовом моего даже исчерпания ресурсов ядра Windows).

Таким образом, невозможно создать «настоящий» недопустимый параметр и получить доступ к ошибкам. Вместо этого я ожидал ERROR_ACCESS_DENIED (но диспетчер задач, запущенный как обычный / не повышенный пользователь, по-прежнему показывает все процессы).

Похоже на нестыковки в винде?

person guest    schedule 10.07.2017