Process.StandardError 属性

定义

获取用于读取应用程序错误输出的流。

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

属性值

可用于读取应用程序的标准错误流的 StreamReader

属性

例外

尚未对 StandardError 流进行重定向定义;请确保 RedirectStandardError 设置为 trueUseShellExecute 设置为 false

- 或 -

已打开 StandardError 流,以使用 BeginErrorReadLine() 进行异步读取操作。

示例

以下示例将 net use 命令与用户提供的参数一起使用来映射网络资源。 然后,它会读取 net 命令的标准错误流,并将其写入控制台。

Process^ myProcess = gcnew Process;
ProcessStartInfo^ myProcessStartInfo = gcnew ProcessStartInfo( "net ",String::Concat( "use ", args[ 0 ] ) );

myProcessStartInfo->UseShellExecute = false;
myProcessStartInfo->RedirectStandardError = true;
myProcess->StartInfo = myProcessStartInfo;
myProcess->Start();

StreamReader^ myStreamReader = myProcess->StandardError;
// Read the standard error of net.exe and write it on to console.
Console::WriteLine( myStreamReader->ReadLine() );
myProcess->Close();
using (Process myProcess = new Process())
{
    ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("net ", "use " + args[0]);

    myProcessStartInfo.UseShellExecute = false;
    myProcessStartInfo.RedirectStandardError = true;
    myProcess.StartInfo = myProcessStartInfo;
    myProcess.Start();

    StreamReader myStreamReader = myProcess.StandardError;
    // Read the standard error of net.exe and write it on to console.
    Console.WriteLine(myStreamReader.ReadLine());
}
Using myProcess As New Process()
    Dim myProcessStartInfo As New ProcessStartInfo("net ", "use " + args(0))

    myProcessStartInfo.UseShellExecute = False
    myProcessStartInfo.RedirectStandardError = True
    myProcess.StartInfo = myProcessStartInfo
    myProcess.Start()

    Dim myStreamReader As StreamReader = myProcess.StandardError
    ' Read the standard error of net.exe and write it on to console.
    Console.WriteLine(myStreamReader.ReadLine())
End Using

注解

当 将 Process 文本写入其标准错误流时,该文本通常显示在主机上。 通过重定向 StandardError 流,可以操作或禁止进程的错误输出。 例如,可以筛选文本、设置不同的格式,或将输出写入控制台和指定的日志文件。

备注

若要使用 StandardError,必须将 设置为 ProcessStartInfo.UseShellExecutefalse,并且必须设置为 ProcessStartInfo.RedirectStandardErrortrue。 否则,从流中 StandardError 读取会引发异常。

重定向的 StandardError 流可以同步或异步读取。 、 和 ReadToEndReadReadLine方法对进程的错误输出流执行同步读取操作。 这些同步读取操作在关联 Process 写入其 StandardError 流或关闭流之前不会完成。

相比之下,对 BeginErrorReadLineStandardError 流启动异步读取操作。 此方法为流输出启用指定的事件处理程序,并立即返回到调用方,后者可以在流输出定向到事件处理程序时执行其他工作。

同步读取操作在从流读取的调用方与写入该 StandardError 流的子进程之间引入了依赖关系。 这些依赖项可能会导致死锁情况。 当调用方从子进程的重定向流中读取时,它依赖于子进程。 调用方等待读取操作,直到子写入流或关闭流。 当子进程写入足够的数据来填充其重定向流时,它依赖于父进程。 子进程等待下一个写入操作,直到父进程从完整流读取或关闭流。 当调用方和子进程相互等待完成操作并且两者都无法继续时,会导致死锁情况。 可以通过评估调用方和子进程之间的依赖关系来避免死锁。

本节中的最后两个示例使用 Start 方法启动名为 Write500Lines.exe的可执行文件。 以下示例包含其源代码。

using System;
using System.IO;

public class Example3
{
   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.

以下示例演示如何从重定向的错误流中读取并等待子进程退出。 它通过在 之前p.WaitForExit调用 p.StandardError.ReadToEnd 来避免死锁条件。 如果父进程先调用 p.WaitForExitp.StandardError.ReadToEnd 子进程写入足够的文本来填充重定向的流,则可能会导致死锁情况。 父进程将无限期等待子进程退出。 子进程将无限期等待父进程从完整 StandardError 流中读取数据。

using System;
using System.Diagnostics;

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

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

      Console.WriteLine($"\nError stream: {output}");
   }
}
// The end of the output produced by the example includes the following:
//      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.RedirectStandardError = 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.StandardError.ReadToEnd()  
        p.WaitForExit()

        Console.WriteLine($"{vbCrLf}Error stream: {output}")
    End Sub
End Module
' The end of the output produced by the example includes the following:
'      Error stream:
'      Successfully wrote 500 lines.

从标准输出流和标准错误流读取所有文本时,也会出现类似的问题。 以下示例对两个流执行读取操作。 它通过在流上 StandardError 执行异步读取操作来避免死锁情况。 如果父进程调用 p.StandardOutput.ReadToEndp.StandardError.ReadToEnd 跟 ,并且子进程写入足够的文本来填充其错误流,则会导致死锁条件。 父进程将无限期等待子进程关闭其 StandardOutput 流。 子进程将无限期等待父进程从完整 StandardError 流中读取数据。

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.

可以使用异步读取操作来避免这些依赖项及其死锁的可能性。 或者,可以通过在单独的线程上创建两个线程并读取每个流的输出来避免死锁情况。

注意

不能在重定向流上混合执行异步读取操作和同步读取操作。 在异步或同步模式下打开 的重定向流 Process 后,该流上的所有进一步读取操作都必须处于同一模式。 例如,请勿在流中StandardError调用 BeginErrorReadLineReadLine ,反之亦然。 但是,可以在不同的模式下读取两个不同的流。 例如,可以调用 BeginOutputReadLine 流,然后调用 ReadLineStandardError

适用于

另请参阅