ProcessStartInfo.RedirectStandardOutput Eigenschaft

Definition

Ruft einen Wert ab, der angibt, ob die Textausgabe einer Anwendung in den StandardOutput-Datenstrom geschrieben wird, oder legt diesen fest.

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

Eigenschaftswert

true, wenn die Ausgabe in StandardOutput geschrieben werden soll; andernfalls false. Der Standardwert ist false.

Beispiele

// 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

Hinweise

Wenn ein Process Text in den Standardstream schreibt, wird dieser Text in der Regel auf der Konsole angezeigt. Wenn Sie auf festlegen RedirectStandardOutputtrue , um den StandardOutput Stream umzuleiten, können Sie die Ausgabe eines Prozesses bearbeiten oder unterdrücken. Beispielsweise können Sie den Text filtern, anders formatieren oder die Ausgabe sowohl in die Konsole als auch in eine festgelegte Protokolldatei schreiben.

Hinweis

Sie müssen auf false festlegenUseShellExecute, wenn Sie auf truefestlegen RedirectStandardOutput möchten. Andernfalls löst das Lesen aus dem StandardOutput Stream eine Ausnahme aus.

Der umgeleitete StandardOutput Stream kann synchron oder asynchron gelesen werden. Methoden wie Read, ReadLineund ReadToEnd führen synchrone Lesevorgänge für den Ausgabedatenstrom des Prozesses aus. Diese synchronen Lesevorgänge werden erst abgeschlossen, wenn die zugeordneten Process Schreibvorgänge in den zugehörigen StandardOutput Stream oder schließen den Stream.

Im Gegensatz dazu BeginOutputReadLine startet asynchrone Lesevorgänge für den StandardOutput Stream. Diese Methode aktiviert einen angegebenen Ereignishandler (siehe OutputDataReceived) für die Streamausgabe und kehrt sofort an den Aufrufer zurück, der andere Aufgaben ausführen kann, während die Streamausgabe an den Ereignishandler weitergeleitet wird.

Hinweis

Die Anwendung, die die asynchrone Ausgabe verarbeitet, sollte die WaitForExit -Methode aufrufen, um sicherzustellen, dass der Ausgabepuffer geleert wurde.

Synchrone Lesevorgänge führen zu einer Abhängigkeit zwischen dem Aufrufer, der aus dem StandardOutput Stream liest, und dem untergeordneten Prozess, der in diesen Stream schreibt. Diese Abhängigkeiten können Deadlockbedingungen verursachen. Wenn der Aufrufer aus dem umgeleiteten Stream eines untergeordneten Prozesses liest, ist er vom untergeordneten Prozess abhängig. Der Aufrufer wartet auf den Lesevorgang, bis das untergeordnete Element in den Stream schreibt oder den Stream schließt. Wenn der untergeordnete Prozess genügend Daten schreibt, um den umgeleiteten Stream auszufüllen, ist er vom übergeordneten Element abhängig. Der untergeordnete Prozess wartet auf den nächsten Schreibvorgang, bis das übergeordnete Element aus dem vollständigen Stream liest oder den Stream schließt. Die Deadlockbedingung ergibt sich, wenn der Aufrufer und der untergeordnete Prozess aufeinander warten, bis ein Vorgang abgeschlossen ist, und keiner kann fortgesetzt werden. Sie können Deadlocks vermeiden, indem Sie Abhängigkeiten zwischen dem Aufrufer und dem untergeordneten Prozess auswerten.

In den letzten beiden Beispielen in diesem Abschnitt wird die Start -Methode verwendet, um eine ausführbare Datei namens Write500Lines.exezu starten. Das folgende Beispiel enthält den Quellcode.

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.

Das folgende Beispiel zeigt, wie Sie aus einem umgeleiteten Stream lesen und warten, bis der untergeordnete Prozess beendet wird. Im Beispiel wird eine Deadlockbedingung vermieden, indem vor p.WaitForExitaufgerufen p.StandardOutput.ReadToEnd wird. Eine Deadlockbedingung kann auftreten, wenn der übergeordnete Prozess vor p.StandardOutput.ReadToEnd aufruft p.WaitForExit und der untergeordnete Prozess genügend Text schreibt, um den umgeleiteten Datenstrom auszufüllen. Der übergeordnete Prozess wartet auf unbestimmte Zeit, bis der untergeordnete Prozess beendet wird. Der untergeordnete Prozess wartet auf unbestimmte Zeit, bis das übergeordnete Element aus dem vollständigen StandardOutput Stream liest.

using System;
using System.Diagnostics;

public class Example2
{
   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%
'      '

Ein ähnliches Problem tritt auf, wenn Sie den gesamten Text sowohl aus dem Standardausgabedatenstrom als auch aus dem Standardfehlerstream lesen. Im folgenden Beispiel wird ein Lesevorgang für beide Streams ausgeführt. Die Deadlockbedingung wird vermieden, indem asynchrone Lesevorgänge für den StandardError Stream ausgeführt werden. Eine Deadlockbedingung ergibt sich, wenn der übergeordnete Prozess gefolgt von p.StandardError.ReadToEnd aufruft p.StandardOutput.ReadToEnd und der untergeordnete Prozess genügend Text schreibt, um den Fehlerdatenstrom auszufüllen. Der übergeordnete Prozess wartet unbegrenzt, bis der untergeordnete Prozess seinen StandardOutput Stream schließt. Der untergeordnete Prozess wartet auf unbestimmte Zeit, bis das übergeordnete Element aus dem vollständigen StandardError Stream liest.

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.

Sie können asynchrone Lesevorgänge verwenden, um diese Abhängigkeiten und deren Deadlockpotenzial zu vermeiden. Alternativ können Sie die Deadlockbedingung vermeiden, indem Sie zwei Threads erstellen und die Ausgabe jedes Streams in einem separaten Thread lesen.

Gilt für:

Weitere Informationen