Process.StandardOutput 属性

定义

获取用于读取应用程序文本输出的流。Gets a stream used to read the textual output of the application.

public:
 property System::IO::StreamReader ^ StandardOutput { System::IO::StreamReader ^ get(); };
public System.IO.StreamReader StandardOutput { get; }
[System.ComponentModel.Browsable(false)]
public System.IO.StreamReader StandardOutput { get; }
member this.StandardOutput : System.IO.StreamReader
[<System.ComponentModel.Browsable(false)>]
member this.StandardOutput : System.IO.StreamReader
Public ReadOnly Property StandardOutput As StreamReader

属性值

StreamReader

StreamReader,可用于读取应用程序的标准输出流。A StreamReader that can be used to read the standard output stream of the application.

属性

例外

尚未对 StandardOutput 流进行重定向定义;请确保 RedirectStandardOutput 设置为 trueUseShellExecute 设置为 falseThe StandardOutput stream has not been defined for redirection; ensure RedirectStandardOutput is set to true and UseShellExecute is set to false.

-or- 已打开 StandardOutput 流,以使用 BeginOutputReadLine() 进行异步读取操作。The StandardOutput stream has been opened for asynchronous read operations with BeginOutputReadLine().

示例

下面的示例运行 ipconfig.exe 命令,并将其标准输出重定向到该示例的控制台窗口。The following example runs the ipconfig.exe command and redirects its standard output to the example's console window.

using namespace System;
using namespace System::IO;
using namespace System::Diagnostics;

int main()
{
    Process^ process = gcnew Process();
    process->StartInfo->FileName = "ipconfig.exe";
    process->StartInfo->UseShellExecute = false;
    process->StartInfo->RedirectStandardOutput = true;
    process->Start();

    // Synchronously read the standard output of the spawned process-> 
    StreamReader^ reader = process->StandardOutput;
    String^ output = reader->ReadToEnd();

    // Write the redirected output to this application's window.
    Console::WriteLine(output);

    process->WaitForExit();
    process->Close();

    Console::WriteLine("\n\nPress any key to exit");
    Console::ReadLine();
    return 0;
}
using System;
using System.IO;
using System.Diagnostics;

class StandardOutputExample
{
    public static void Main()
    {
        using (Process process = new Process())
        {
            process.StartInfo.FileName = "ipconfig.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();

            // Synchronously read the standard output of the spawned process.
            StreamReader reader = process.StandardOutput;
            string output = reader.ReadToEnd();

            // Write the redirected output to this application's window.
            Console.WriteLine(output);

            process.WaitForExit();
        }

        Console.WriteLine("\n\nPress any key to exit.");
        Console.ReadLine();
    }
}
Imports System.IO
Imports System.Diagnostics

Module Module1
    Sub Main()
        Using process As New Process()
            process.StartInfo.FileName = "ipconfig.exe"
            process.StartInfo.UseShellExecute = False
            process.StartInfo.RedirectStandardOutput = True
            process.Start()

            ' Synchronously read the standard output of the spawned process. 
            Dim reader As StreamReader = process.StandardOutput
            Dim output As String = reader.ReadToEnd()
            Console.WriteLine(output)

            process.WaitForExit()
        End Using

        Console.WriteLine(Environment.NewLine + Environment.NewLine + "Press any key to exit.")
        Console.ReadLine()
    End Sub
End Module

注解

Process 向标准流写入文本时,该文本通常显示在控制台上。When a Process writes text to its standard stream, that text is normally displayed on the console. 通过重定向 StandardOutput 流,你可以操作或取消进程的输出。By redirecting 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.

备注

若要使用 StandardOutput ,必须将设置 ProcessStartInfo.UseShellExecutefalse ,并且必须将设置 ProcessStartInfo.RedirectStandardOutputtrueTo use StandardOutput, you must set ProcessStartInfo.UseShellExecute to false, and you must set ProcessStartInfo.RedirectStandardOutput to true. 否则,从流中读取会 StandardOutput 引发异常。Otherwise, reading from the StandardOutput stream throws an exception.

重定向的 StandardOutput 流可以同步或异步读取。The redirected StandardOutput stream can be read synchronously or asynchronously. 方法(如 ReadReadLine 和) ReadToEnd 在进程的输出流上执行同步读取操作。Methods such as Read, ReadLine, and ReadToEnd perform synchronous read operations on the output stream of the process. 在对 Process 其流进行关联的写入或关闭流之前,这些同步读取操作不会完成 StandardOutputThese synchronous read operations do not complete until the associated Process writes to its StandardOutput stream, or closes the stream.

与此相反, BeginOutputReadLine 对流启动异步读取操作 StandardOutputIn contrast, BeginOutputReadLine starts asynchronous read operations on the StandardOutput stream. 此方法将为流输出启用指定的事件处理程序,并立即返回到调用方,当流输出定向到事件处理程序时,该处理程序可以执行其他操作。This method enables a designated event handler 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.

同步读取操作介绍了从流读取的调用方 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 result in deadlock conditions. 当调用方从子进程的重定向流中进行读取时,它依赖于子进程。When the caller reads from the redirected stream of a child process, it is dependent on the child. 调用方等待读取操作,直到子级写入流或关闭流为止。The caller waits on 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 on 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 on each other to complete an operation, and neither can proceed. 您可以通过计算调用方和子进程之间的依赖关系来避免死锁。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.WaitForExitThe 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. 子进程会无限期地等待父进程从整个流中读取 StandardOutputThe 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. 它通过对流执行异步读取操作来避免死锁情况 StandardErrorIt 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. 子进程会无限期地等待父进程从整个流中读取 StandardErrorThe 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.

备注

不能对重定向的流混合使用异步和同步读取操作。You cannot mix asynchronous and synchronous read operations on a redirected stream. Process在异步或同步模式下打开的重定向流后,对该流进行的所有进一步读取操作都必须处于同一模式。Once the redirected stream of a Process is opened in either asynchronous or synchronous mode, all further read operations on that stream must be in the same mode. 例如,不要在 BeginOutputReadLine ReadLine 对流上调用, StandardOutput 反之亦然。For example, do not follow BeginOutputReadLine with a call to ReadLine on the StandardOutput stream, or vice versa. 但是,可以在不同模式下读取两个不同的流。However, you can read two different streams in different modes. 例如,可以调用 BeginOutputReadLine ,然后调用流的 ReadLine StandardErrorFor example, you can call BeginOutputReadLine and then call ReadLine for the StandardError stream.

适用于

另请参阅