Чтение стандартного вывода другого процесса в С++

В Windows есть способ запустить процесс на С++, а затем прочитать то, что он выдал в стандартный вывод, когда это будет сделано? Процесс должен быть запущен с повышенными привилегиями (в Vista или более поздних версиях), если это необходимо.

В настоящее время я использую ShellExecuteEx() для запуска процесса и выполнения цикла while до тех пор, пока GetExitCodeProcess() больше не будет возвращать STILL_ACTIVE через параметр lpExitCode (с вызовом WaitForSingleObject(), выполняющим ожидание 100 мс во время каждой итерации).


person RobH    schedule 04.11.2010    source источник
comment
Можете ли вы перенаправить стандартный вывод в именованный канал при запуске процесса? (Не разработчик С++, поэтому делаю комментарий)   -  person Michael Stum    schedule 04.11.2010
comment
Проблема в том, что для запуска процесса с повышенными правами вы должны использовать ShellExecuteEx() с глаголом runas. И ShellExecuteEx() не поддерживает перенаправление вывода AFAICT.   -  person Alex Jasmin    schedule 04.11.2010


Ответы (4)


Нет простого способа сделать это.

Вызов ShellExecuteEx() с глаголом runas отправляет сообщение RPC в службу AppInfo NT, которая затем запускает приложение из сеанса с повышенными правами. Не существует API для простого подключения ввода/вывода процесса с повышенными правами к вашему приложению.

Томас Хрушка в своей статье Code Project представляет свою реализацию CreateProcessElevated() функции. это решает.

Вместо прямого запуска программы с повышенными правами CreateProcessElevated() полагается на другой исполняемый файл, который получает имя именованных каналов stdin, stdout, stderr и воссоздает свои дескрипторы в сеансе с повышенными правами перед вызовом CreateProcess().

person Alex Jasmin    schedule 04.11.2010
comment
Мне нравится решение Code Project. К сожалению, поскольку для этого требуется отдельная DLL, я не смогу использовать ее для своего конкретного проекта, который является загрузочным приложением установщика. (Вздох! Вернемся к чертежной доске, наверное.) - person RobH; 04.11.2010

Вы должны заменить использование ShellExecuteEx на CreateProcess. . Аргумент lpStartupInfo позволяет стандартному и стандартные дескрипторы процесса. Просто создайте анонимный канал с помощью CreatePipe, который вы передать в качестве аргументов. В этой статье MSDN приведен пример того, как сделай это.

person zdan    schedule 04.11.2010
comment
Но CreateProcess() нельзя использовать для запуска процесса с повышенными правами, если родительский процесс также не имеет повышенных прав. - person Ian Goldby; 14.09.2011

Вам нужно создать именованный канал для дочернего процесса. Эта статья MSDN объясняет и содержит примеры кода .

Вы должны быть в состоянии получить это происходит от этого.

person Byron Whitlock    schedule 04.11.2010
comment
К сожалению, это решение использует CreateProcess(), а не ShellExecuteEx(). - person Jon Trauntvein; 06.06.2012

Не можете ли вы использовать CreateProcess/ShellExecuteEx для выполнения оболочки cmd с перенаправлением stdout/stderr, который, в свою очередь, вызывает ваш процесс?

«cmd /c YourProcess.exe {параметры}» и т. д.?

person JimR    schedule 04.11.2010