Есть ли лучший способ перенаправить стандартный вывод в C ++ / CLI, чем с помощью system ()? - PullRequest
0 голосов
/ 29 августа 2011

В 2 частях кода C ++ / CLI, над которым я работаю, программе нужно запустить другой исполняемый файл и перенаправить вывод STDOUT в файл. Его пытались двумя разными способами, и только один из двух в настоящее время работает. Программа работает на Windows XP.

Первый раздел собирает длинный символ *, который выглядит примерно так:

char* exepath = "start/B /D\\root\\bin \\root\\bin\\process.exe 1>\\root\\logs\\process_STDOUT.txt"

Тогда код просто вызывает

Status = system(exepath);

Это работает нормально: он запускает process.exe и создает файл process_STDOUT.txt, как и ожидалось.

Второй раздел пытается сделать то же самое, используя объект ProcessStartInfo. Он успешно запускает process.exe, но не создает перенаправленный выходной файл .txt. Вот упрощенная версия этого кода:

 Process p = gcnew Process();
 ProcessStartInfo^ s = gcnew ProcessStartInfo();
 s->FileName         = "\\root\\bin\\process.exe";
 s->WindowStyle      = ProcessWindowStyle::Hidden;
 s->CreateNoWindow   = true;
 s->UseShellExecute  = false;
 s->Arguments        = "1>\\root\\logs\\process_STDOUT.txt";
 p->StartInfo        = s;
 p->Start();

Что-то не так с этим кодом? И если нет, то возвращение к простому вызову системы (exepath) - мой единственный вариант или есть другие?

Ответы [ 3 ]

2 голосов
/ 29 августа 2011

Функция system вызывает системный интерпретатор командной строки, который в Windows обычно cmd.exe . Это программа, которая анализирует синтаксис перенаправления ввода / вывода. Программа, которую вы запускаете, не знает, что означает >; это интерпретирует это как первый символ фактического аргумента командной строки. (Подумайте об этом - когда-нибудь вы когда-либо писали код переадресации командной строки в ваших программах командной строки? Нет, конечно, нет. Ни один из авторов не сделал этого. ехе .)

Так вот почему ваш ProcessStartInfo метод не перенаправляет ввод / вывод. Для этого см. Здесь вопрос о перенаправлении stdin и stdout в .Net .

Поскольку вы все равно перенаправляете вывод в файл, ваш текущий код system должен быть в порядке. Более программируемые способы перенаправления необходимы, когда вы хотите собрать выходные данные в вашей программе, а не в файле.

1 голос
/ 29 августа 2011

Оформить эту статью.Примечательно:

/* Setup Redirect */
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;

/* Capture Output */
StreamWriter inputWriter = process.StandardInput;
StreamReader outputReader = process.StandardOutput;
StreamReader errorReader = process.StandardError;
process.WaitForExit();

Передача "1>\\root\\logs\\process_STDOUT.txt" в качестве аргумента не совпадает с перенаправлением

0 голосов
/ 29 августа 2011

"команда канала" не передается программе в качестве параметра; оболочка интерпретирует его, и сама программа не знает, что ее вывод перенаправляется в файл. Так что вы не хотите передавать подобные вещи в качестве аргумента.

Однако класс Program имеет свойства потоков StandardOutput и StandardError, которые помогут вам захватить вывод. Вам просто нужно указать (в вашем ProcessStartInfo объекте), что вы хотите перенаправить вывод.

s->RedirectStandardOutput = true;
s->RedirectStandardError = true;

После этой точки вы сможете использовать p->StandardOutput и p->StandardError, чтобы получить вывод потока.

...