Condividi tramite


ProcessStartInfo.RedirectStandardOutput Proprietà

Definizione

Ottiene o imposta un valore che indica se l'output testuale di un'applicazione viene scritto nel flusso StandardOutput.

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

Valore della proprietà

true se l'output deve essere scritto in StandardOutput; in caso contrario, false. Il valore predefinito è false.

Esempio

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

Commenti

Quando un Process testo scrive nel flusso standard, questo testo viene in genere visualizzato nella console. Impostando RedirectStandardOutput su per true reindirizzare il flusso, è possibile modificare o eliminare l'output StandardOutput di un processo. Ad esempio, è possibile filtrare il testo, formattarlo in modo diverso o scrivere l'output nella console e in un file di log designato.

Nota

È necessario impostare su false se si vuole impostare UseShellExecuteRedirectStandardOutput su true. In caso contrario, la lettura dal flusso genera un'eccezione StandardOutput .

Il flusso reindirizzato StandardOutput può essere letto in modo sincrono o asincrono. Metodi come Read, ReadLinee ReadToEnd eseguono operazioni di lettura sincrone nel flusso di output del processo. Queste operazioni di lettura sincrone non vengono completate fino a quando le scritture StandardOutput associate Process al flusso non vengono completate o chiude il flusso.

Al contrario, BeginOutputReadLine avvia operazioni di lettura asincrone nel StandardOutput flusso. Questo metodo abilita un gestore eventi designato (vedere OutputDataReceived) per l'output del flusso e restituisce immediatamente al chiamante, che può eseguire altre operazioni mentre l'output del flusso viene indirizzato al gestore eventi.

Nota

L'applicazione che elabora l'output asincrono deve chiamare il WaitForExit metodo per assicurarsi che il buffer di output sia stato scaricato.

Le operazioni di lettura sincrone introducono una dipendenza tra la lettura del chiamante dal StandardOutput flusso e il processo figlio che scrive in tale flusso. Queste dipendenze possono causare condizioni di deadlock. Quando il chiamante legge dal flusso reindirizzato di un processo figlio, dipende dal figlio. Il chiamante attende l'operazione di lettura fino a quando il figlio scrive nel flusso o chiude il flusso. Quando il processo figlio scrive dati sufficienti per riempire il flusso reindirizzato, dipende dall'elemento padre. Il processo figlio attende l'operazione di scrittura successiva fino a quando l'elemento padre legge dal flusso completo o chiude il flusso. La condizione deadlock risulta quando il chiamante e il processo figlio attendeno l'uno dall'altro di completare un'operazione e nessuno dei due può continuare. È possibile evitare deadlock valutando le dipendenze tra il chiamante e il processo figlio.

Gli ultimi due esempi di questa sezione usano il Start metodo per avviare un eseguibile denominato Write500Lines.exe. L'esempio seguente contiene il codice sorgente.

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.

Nell'esempio seguente viene illustrato come leggere da un flusso reindirizzato e attendere l'uscita del processo figlio. Nell'esempio viene evitata una condizione di deadlock chiamando p.StandardOutput.ReadToEnd prima p.WaitForExitdi . Una condizione di deadlock può causare se il processo padre chiama p.WaitForExit prima p.StandardOutput.ReadToEnd e il processo figlio scrive testo sufficiente per riempire il flusso reindirizzato. Il processo padre attende in modo indefinito l'uscita dal processo figlio. Il processo figlio attende in modo indefinito che l'elemento padre venga letto dal flusso completo StandardOutput .

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%
'      '

Si verifica un problema simile quando si legge tutto il testo sia dall'output standard che dai flussi di errore standard. Nell'esempio seguente viene eseguita un'operazione di lettura in entrambi i flussi. Evita la condizione di deadlock eseguendo operazioni di lettura asincrone nel StandardError flusso. Una condizione di deadlock restituisce se il processo padre chiama p.StandardOutput.ReadToEnd e p.StandardError.ReadToEnd il processo figlio scrive testo sufficiente per riempire il flusso di errori. Il processo padre attende in modo indefinito il processo figlio per chiudere StandardOutput il flusso. Il processo figlio attende in modo indefinito che l'elemento padre venga letto dal flusso completo 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.

È possibile usare operazioni di lettura asincrone per evitare queste dipendenze e il potenziale di deadlock. In alternativa, è possibile evitare la condizione di deadlock creando due thread e leggendo l'output di ogni flusso in un thread separato.

Si applica a

Vedi anche