Как я могу скопировать стандартный вывод процесса (копировать, а не перенаправлять)?

#c# #.net #unit-testing #mstest #stdout

#c# #.net #модульное тестирование #mstest #стандартный вывод

Вопрос:

есть много примеров, которые показывают, как перенаправить стандартный вывод другого приложения. Однако я хотел бы, чтобы приложение сохраняло свой стандартный вывод и получало копию стандартного вывода только в моем родительском процессе. Возможно ли это?

Мой сценарий: у меня есть несколько тестов (с использованием Visual Studio Test Runner), которые запускают внешний процесс (сервер) для их тестирования. Сервер выводит много полезной отладочной информации в своем стандартном выводе, который я хотел бы включить в результаты моего тестирования.

Я могу захватить вывод процесса и вывести его с помощью трассировки.WriteLine, чтобы он отображался в деталях теста позже. Однако было бы неплохо увидеть окно сервера с его выводом во время выполнения теста, чтобы увидеть текущий прогресс (тест может выполняться долгое время).

Поэтому я ищу способы скопировать эту информацию вместо простого перенаправления.

Есть идеи?

Комментарии:

1. ммм, возможно, поток Echo / Tee может помочь? codeproject.com/KB/dotnet/echostream.aspx (погуглите «c # tee stream», чтобы найти еще много просмотров)

2. Не уверен в этом, поскольку я не могу протестировать здесь, но может быть правдой, что процесс. Событие OutputDataReceived выдает желаемое поведение, см.: msdn.microsoft.com/en-us/library /…

3. OutputDataReceived — это то, что я использую, но для этого требуется перенаправление потока и, следовательно, удаляет вывод из окна консоли сервера…

Ответ №1:

Будет ли это работать для вас?

         var outputText = new StringBuilder();
        var errorText = new StringBuilder();

        using (var process = Process.Start(new ProcessStartInfo(
            @"YourProgram.exe",
            "arguments go here")
            {
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                UseShellExecute = false
            }))
        {
            process.OutputDataReceived  = (sendingProcess, outLine) =>
            {
                outputText.AppendLine(outLine.Data); // capture the output
                Console.Out.WriteLine(outLine.Data); // echo the output
            }

            process.ErrorDataReceived  = (sendingProcess, errorLine) =>
            {
                errorText.AppendLine(errorLine.Data); // capture the error
                Console.Error.WriteLine(errorLine.Data); // echo the error
            }

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
            // At this point, errorText and outputText StringBuilders
            // have the captured text.  The event handlers already echoed the
            // output back to the console.
        }
  

Комментарии:

1. Это. Скопируйте вывод консоли, перенаправив его в составной класс вывода, который будет «транслировать» вывод нескольким «слушателям». Существует много шаблонов; это, вероятно, один из менее сложных в реализации.

2. проблема в том, что этот код выполняется как часть модульного теста внутри тестового модуля Microsoft Visual Studio. у самого тестового запуска нет окна консоли…

Ответ №2:

Как насчет написания небольшой программы, которая перенаправляет стандартный ввод в стандартный вывод, в то же время делая с ним что-то еще?

Затем вы можете заменить команду, которая запускает серверный процесс, на ту, которая запускает его и передает его вывод в указанную выше утилиту. Таким образом, вы будете иметь программный доступ к выводу и видеть его в режиме реального времени в окне вывода.

Комментарии:

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

2. Я решил, что небольшого преимущества отображения окна сервера недостаточно, чтобы еще больше усложнить мой тестовый код. Однако ваша идея сработала бы с небольшой модификацией: захват вывода моего сервера в тестовом коде и отправка его в эту программу «echo», которая просто отобразила бы его в консоли.