ProcessStartInfo.RedirectStandardOutput ProcessStartInfo.RedirectStandardOutput ProcessStartInfo.RedirectStandardOutput ProcessStartInfo.RedirectStandardOutput Property

Определение

Позволяет получить или задать значение для определения того, записываются ли текстовые выходные данные приложения в поток StandardOutput.Gets or sets a value that indicates whether the textual output of an application is written to the StandardOutput stream.

public:
 property bool RedirectStandardOutput { bool get(); void set(bool value); };
public bool RedirectStandardOutput { get; set; }
member this.RedirectStandardOutput : bool with get, set
Public Property RedirectStandardOutput As Boolean

Значение свойства

Значение true, если выходные данные должны записываться в StandardOutput; в противном случае — значение false.true if output should be written to StandardOutput; otherwise, false. Значение по умолчанию — false.The default is false.

Примеры

// Run "cl.exe /cld stdstr.cpp /link /out:sample.exe". UseShellExecute is false because we're specifying
// an executable directly and in this case depending on it being in a PATH folder. By setting
// RedirectStandardOutput to true, the output of cl.exe is directed to the Process.StandardOutput stream
// which is then displayed in this console window directly.    
Process^ compiler = gcnew Process;
compiler->StartInfo->FileName = "cl.exe";
compiler->StartInfo->Arguments = "/clr stdstr.cpp /link /out:sample.exe";
compiler->StartInfo->UseShellExecute = false;
compiler->StartInfo->RedirectStandardOutput = true;
compiler->Start();

Console::WriteLine( compiler->StandardOutput->ReadToEnd() );

compiler->WaitForExit();
// Run "csc.exe /r:System.dll /out:sample.exe stdstr.cs". UseShellExecute is false because we're specifying
// an executable directly and in this case depending on it being in a PATH folder. By setting
// RedirectStandardOutput to true, the output of csc.exe is directed to the Process.StandardOutput stream
// which is then displayed in this console window directly.    
using (Process compiler = new Process())
{
    compiler.StartInfo.FileName = "csc.exe";
    compiler.StartInfo.Arguments = "/r:System.dll /out:sample.exe stdstr.cs";
    compiler.StartInfo.UseShellExecute = false;
    compiler.StartInfo.RedirectStandardOutput = true;
    compiler.Start();

    Console.WriteLine(compiler.StandardOutput.ReadToEnd());

    compiler.WaitForExit();
}
' Run "vbc.exe /reference:Microsoft.VisualBasic.dll /out:sample.exe stdstr.vb". UseShellExecute is False 
' because we're specifying an executable directly and in this case depending on it being in a PATH folder. 
' By setting RedirectStandardOutput to True, the output of csc.exe is directed to the Process.StandardOutput 
' stream which is then displayed in this console window directly.    
Using compiler As New Process()
    compiler.StartInfo.FileName = "vbc.exe"
    compiler.StartInfo.Arguments = "/reference:Microsoft.VisualBasic.dll /out:sample.exe stdstr.vb"
    compiler.StartInfo.UseShellExecute = False
    compiler.StartInfo.RedirectStandardOutput = True
    compiler.Start()

    Console.WriteLine(compiler.StandardOutput.ReadToEnd())

    compiler.WaitForExit()
End Using

Комментарии

Когда Process записывает текст в стандартный поток, этот текст обычно отображается в консоли.When a Process writes text to its standard stream, that text is typically displayed on the console. Установив RedirectStandardOutput в true для перенаправления потока StandardOutput, можно управлять и подавлять вывод процесса.By setting RedirectStandardOutput to true to redirect the StandardOutput stream, you can manipulate or suppress the output of a process. Например, можно отфильтровать текст, отформатировать его по-другому или записать выходные данные как в консоль, так и в назначенный файл журнала.For example, you can filter the text, format it differently, or write the output to both the console and a designated log file.

Примечание

Необходимо задать UseShellExecute равным false, если требуется установить RedirectStandardOutput в true.You must set UseShellExecute to false if you want to set RedirectStandardOutput to true. В противном случае при чтении из потока StandardOutput возникает исключение.Otherwise, reading from the StandardOutput stream throws an exception.

Перенаправленный поток StandardOutput можно считать синхронным или асинхронным.The redirected StandardOutput stream can be read synchronously or asynchronously. Такие методы, как Read, ReadLine и ReadToEnd выполняют синхронные операции чтения в потоке вывода процесса.Methods such as Read, ReadLine, and ReadToEnd perform synchronous read operations on the output stream of the process. Эти операции синхронного чтения не завершаются, пока связанный Process не запишет в свой поток StandardOutput или не закроет поток.These synchronous read operations do not complete until the associated Process writes to its StandardOutput stream, or closes the stream.

Напротив, BeginOutputReadLine запускает асинхронные операции чтения в потоке StandardOutput.In contrast, BeginOutputReadLine starts asynchronous read operations on the StandardOutput stream. Этот метод включает назначенный обработчик событий (см. OutputDataReceived) для выходного потока и немедленно возвращается вызывающему объекту, который может выполнять другие действия, пока потоковый выход направляется в обработчик событий.This method enables a designated event handler (see OutputDataReceived) for the stream output and immediately returns to the caller, which can perform other work while the stream output is directed to the event handler.

Примечание

Приложение, обрабатывающее асинхронный вывод, должно вызвать метод WaitForExit, чтобы убедиться, что выходной буфер был сброшен.The application that is processing the asynchronous output should call the WaitForExit method to ensure that the output buffer has been flushed.

Синхронные операции чтения представляют зависимость между вызывающим объектом, читающим поток StandardOutput, и дочерним процессом, записывающим в этот поток.Synchronous read operations introduce a dependency between the caller reading from the StandardOutput stream and the child process writing to that stream. Эти зависимости могут вызвать условия взаимоблокировки.These dependencies can cause deadlock conditions. Когда вызывающий объект считывает данные из перенаправленного потока дочернего процесса, он зависит от дочернего объекта.When the caller reads from the redirected stream of a child process, it is dependent on the child. Вызывающий объект ожидает операции чтения до тех пор, пока дочерние записи не будут записаны в поток или закроет поток.The caller waits for the read operation until the child writes to the stream or closes the stream. Когда дочерний процесс записывает достаточно данных для заполнения перенаправляемого потока, он зависит от родителя.When the child process writes enough data to fill its redirected stream, it is dependent on the parent. Дочерний процесс ожидает следующей операции записи, пока родитель не считывает из полного потока или не закрывает поток.The child process waits for the next write operation until the parent reads from the full stream or closes the stream. Условие взаимоблокировки вызывается, когда вызывающий и дочерний процесс ожидают друг друга для выполнения операции, и ни один из них не может продолжить работу.The deadlock condition results when the caller and child process wait for each other to complete an operation, and neither can continue. Можно избежать взаимоблокировок, оценивая зависимости между вызывающим и дочерним процессами.You can avoid deadlocks by evaluating dependencies between the caller and child process.

В двух последних примерах в этом разделе используется метод Start для запуска исполняемого файла с именем Write500Lines. exe.The last two examples in this section use the Start method to launch an executable named Write500Lines.exe. В следующем примере содержится исходный код.The following example contains its source code.

using System;
using System.IO;

public class Example
{
   public static void Main()
   {
      for (int ctr = 0; ctr < 500; ctr++)
         Console.WriteLine($"Line {ctr + 1} of 500 written: {ctr + 1/500.0:P2}");

      Console.Error.WriteLine("\nSuccessfully wrote 500 lines.\n");
   }
}
// The example displays the following output:
//      The last 50 characters in the output stream are:
//      ' 49,800.20%
//      Line 500 of 500 written: 49,900.20%
//'
//
//      Error stream: Successfully wrote 500 lines.
Imports System.IO

Public Module Example
   Public Sub Main()
      For ctr As Integer = 0 To 499
         Console.WriteLine($"Line {ctr + 1} of 500 written: {ctr + 1/500.0:P2}")
      Next

      Console.Error.WriteLine($"{vbCrLf}Successfully wrote 500 lines.{vbCrLf}")
   End Sub
End Module
' The example displays the following output:
'      The last 50 characters in the output stream are:
'      ' 49,800.20%
'      Line 500 of 500 written: 49,900.20%
'
'
'      Error stream: Successfully wrote 500 lines.

В следующем примере показано, как выполнить чтение из перенаправленного потока и дождаться завершения дочернего процесса.The following example shows how to read from a redirected stream and wait for the child process to exit. В этом примере предотвращается условие взаимоблокировки путем вызова p.StandardOutput.ReadToEnd до p.WaitForExit.The example avoids a deadlock condition by calling p.StandardOutput.ReadToEnd before p.WaitForExit. Условие взаимоблокировки может возникнуть, если родительский процесс вызывает p.WaitForExit до p.StandardOutput.ReadToEnd, а дочерний процесс записывает достаточно текста для заполнения перенаправленного потока.A deadlock condition can result if the parent process calls p.WaitForExit before p.StandardOutput.ReadToEnd and the child process writes enough text to fill the redirected stream. Родительский процесс ожидает завершения дочернего процесса в течение неограниченного времени.The parent process would wait indefinitely for the child process to exit. Дочерний процесс в течение неограниченного времени будет ждать, пока родительский поток не будет считаться из полного потока StandardOutput.The child process would wait indefinitely for the parent to read from the full StandardOutput stream.

using System;
using System.Diagnostics;

public class Example
{
   public static void Main()
   {
      var p = new Process();  
      p.StartInfo.UseShellExecute = false;  
      p.StartInfo.RedirectStandardOutput = true;  
      p.StartInfo.FileName = "Write500Lines.exe";  
      p.Start();  

      // To avoid deadlocks, always read the output stream first and then wait.  
      string output = p.StandardOutput.ReadToEnd();  
      p.WaitForExit();

      Console.WriteLine($"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'");
   }
}
// The example displays the following output:
//      Successfully wrote 500 lines.
//
//      The last 50 characters in the output stream are:
//      ' 49,800.20%
//      Line 500 of 500 written: 49,900.20%
//      '
Imports System.Diagnostics'

Public Module Example
   Public Sub Main()
      Dim p As New Process()
      p.StartInfo.UseShellExecute = False  
      p.StartInfo.RedirectStandardOutput = True  
      p.StartInfo.FileName = "Write500Lines.exe"  
      p.Start() 

      ' To avoid deadlocks, always read the output stream first and then wait.  
      Dim output As String = p.StandardOutput.ReadToEnd()  
      p.WaitForExit()

      Console.WriteLine($"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'")
   End Sub
End Module
' The example displays the following output:
'      Successfully wrote 500 lines.
'
'      The last 50 characters in the output stream are:
'      ' 49,800.20%
'      Line 500 of 500 written: 49,900.20%
'      '

Подобная ситуация возникает при чтении всего текста из стандартных выходных и стандартных потоков ошибок.There is a similar issue when you read all text from both the standard output and standard error streams. В следующем примере выполняется операция чтения для обоих потоков.The following example performs a read operation on both streams. Это позволяет избежать условия взаимоблокировки, выполняя асинхронные операции чтения в потоке StandardError.It avoids the deadlock condition by performing asynchronous read operations on the StandardError stream. Условие взаимоблокировки дает результат, если родительский процесс вызывает p.StandardOutput.ReadToEnd, за которым следует p.StandardError.ReadToEnd, а дочерний процесс записывает достаточно текста для заполнения потока ошибок.A deadlock condition results if the parent process calls p.StandardOutput.ReadToEnd followed by p.StandardError.ReadToEnd and the child process writes enough text to fill its error stream. Родительский процесс будет ждать неограниченного времени, пока дочерний процесс не закроет свой поток StandardOutput.The parent process would wait indefinitely for the child process to close its StandardOutput stream. Дочерний процесс в течение неограниченного времени будет ждать, пока родительский поток не будет считаться из полного потока StandardError.The child process would wait indefinitely for the parent to read from the full StandardError stream.

using System;
using System.Diagnostics;

public class Example
{
   public static void Main()
   {
      var p = new Process();  
      p.StartInfo.UseShellExecute = false;  
      p.StartInfo.RedirectStandardOutput = true;  
      string eOut = null;
      p.StartInfo.RedirectStandardError = true;
      p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => 
                                 { eOut += e.Data; });
      p.StartInfo.FileName = "Write500Lines.exe";  
      p.Start();  

      // To avoid deadlocks, use an asynchronous read operation on at least one of the streams.  
      p.BeginErrorReadLine();
      string output = p.StandardOutput.ReadToEnd();  
      p.WaitForExit();

      Console.WriteLine($"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'");
      Console.WriteLine($"\nError stream: {eOut}");
   }
}
// The example displays the following output:
//      The last 50 characters in the output stream are:
//      ' 49,800.20%
//      Line 500 of 500 written: 49,900.20%
//      '
//
//      Error stream: Successfully wrote 500 lines.

Imports System.Diagnostics

Public Module Example
   Public Sub Main()
      Dim p As New Process()  
      p.StartInfo.UseShellExecute = False  
      p.StartInfo.RedirectStandardOutput = True  
      Dim eOut As String = Nothing
      p.StartInfo.RedirectStandardError = True
      AddHandler p.ErrorDataReceived, Sub(sender, e) eOut += e.Data 
      p.StartInfo.FileName = "Write500Lines.exe"  
      p.Start()  

      ' To avoid deadlocks, use an asynchronous read operation on at least one of the streams.  
      p.BeginErrorReadLine()
      Dim output As String = p.StandardOutput.ReadToEnd()  
      p.WaitForExit()

      Console.WriteLine($"The last 50 characters in the output stream are:{vbCrLf}'{output.Substring(output.Length - 50)}'")
      Console.WriteLine($"{vbCrLf}Error stream: {eOut}")
   End Sub
End Module
' The example displays the following output:
'      The last 50 characters in the output stream are:
'      ' 49,800.20%
'      Line 500 of 500 written: 49,900.20%
'      '
'
'      Error stream: Successfully wrote 500 lines.

Асинхронные операции чтения можно использовать во избежание этих зависимостей и их возможных взаимоблокировок.You can use asynchronous read operations to avoid these dependencies and their deadlock potential. Кроме того, можно избежать условия взаимоблокировки, создав два потока и прочитав выходные данные каждого потока в отдельном потоке.Alternately, you can avoid the deadlock condition by creating two threads and reading the output of each stream on a separate thread.

Применяется к

Дополнительно