ProcessStartInfo.RedirectStandardError 属性
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
获取或设置指示是否将应用程序的错误输出写入 StandardError 流中的值。
public:
property bool RedirectStandardError { bool get(); void set(bool value); };
public bool RedirectStandardError { get; set; }
member this.RedirectStandardError : bool with get, set
Public Property RedirectStandardError As Boolean
属性值
如果错误输出应写入 StandardError,则为 true
;否则为 false
。 默认值为 false
。
示例
以下示例将 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 流,可以操作或禁止显示进程的错误输出。 例如,可以筛选文本、设置不同的格式,或将输出写入控制台和指定的日志文件。
注意
如果要将 设置为 UseShellExecute ,则必须将 设置为 RedirectStandardErrortrue
。false
否则,从流中 StandardError 读取将引发异常。
重定向的 StandardError 流可以同步或异步读取。 和 等ReadReadLineReadToEnd方法对进程的错误输出流执行同步读取操作。 在关联的 Process 写入到其 StandardError 流或关闭流之前,这些同步读取操作不会完成。
相反,对 BeginErrorReadLineStandardError 流启动异步读取操作。 此方法为流输出启用指定的事件处理程序,并立即返回给调用方,调用方可以在流输出定向到事件处理程序时执行其他工作。
注意
正在处理异步输出的应用程序应调用 Process.WaitForExit 方法,以确保已刷新输出缓冲区。
同步读取操作在从流读取的调用方与写入该 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.WaitForExit
, p.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.
从标准输出流和标准错误流读取所有文本时,也会出现类似的问题。 例如,以下 C# 代码对两个流执行读取操作。 它通过在流上 StandardError 执行异步读取操作来避免死锁条件。 如果父进程调用 p.StandardOutput.ReadToEnd
后跟 p.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.
可以使用异步读取操作来避免这些依赖项及其死锁的可能性。 或者,可以通过创建两个线程并在单独的线程上读取每个流的输出来避免死锁情况。