ProcessStartInfo.RedirectStandardOutput Propiedad
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Obtiene o establece un valor que indica si la salida de una aplicación se escribe en la secuencia de 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
Valor de propiedad
true
si la salida se debe escribir en StandardOutput; de lo contrario, es false
. De manera predeterminada, es false
.
Ejemplos
// 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
Comentarios
Cuando un Process objeto escribe texto en su secuencia estándar, ese texto se muestra normalmente en la consola. Al establecer RedirectStandardOutput en para true
redirigir la StandardOutput secuencia, puede manipular o suprimir la salida de un proceso. Por ejemplo, puede filtrar el texto, formatearlo de forma diferente o escribir la salida en la consola y en un archivo de registro designado.
Nota
Debe establecer UseShellExecutefalse
en si desea establecer en RedirectStandardOutputtrue
. De lo contrario, la lectura de la StandardOutput secuencia produce una excepción.
La secuencia redirigida StandardOutput se puede leer de forma sincrónica o asincrónica. Métodos como Read, ReadLiney ReadToEnd realizan operaciones de lectura sincrónicas en el flujo de salida del proceso. Estas operaciones de lectura sincrónicas no se completan hasta que las escrituras asociadas Process a su StandardOutput secuencia o cierran la secuencia.
En cambio, BeginOutputReadLine inicia operaciones de lectura asincrónicas en la StandardOutput secuencia. Este método habilita un controlador de eventos designado (vea OutputDataReceived) para la salida de la secuencia y vuelve inmediatamente al autor de la llamada, que puede realizar otro trabajo mientras la salida de la secuencia se dirige al controlador de eventos.
Nota
La aplicación que procesa la salida asincrónica debe llamar al WaitForExit método para asegurarse de que se ha vaciado el búfer de salida.
Las operaciones de lectura sincrónicas presentan una dependencia entre la lectura del autor de la llamada desde la StandardOutput secuencia y el proceso secundario que escribe en esa secuencia. Estas dependencias pueden causar condiciones de interbloqueo. Cuando el autor de la llamada lee desde la secuencia redirigida de un proceso secundario, depende del elemento secundario. El autor de la llamada espera a la operación de lectura hasta que el elemento secundario escribe en la secuencia o cierra la secuencia. Cuando el proceso secundario escribe suficientes datos para rellenar su flujo redirigido, depende del elemento primario. El proceso secundario espera a la siguiente operación de escritura hasta que el elemento primario lee de la secuencia completa o cierra la secuencia. La condición de interbloqueo se produce cuando el llamador y el proceso secundario esperan entre sí para completar una operación y ninguno puede continuar. Puede evitar interbloqueos mediante la evaluación de dependencias entre el autor de la llamada y el proceso secundario.
Los dos últimos ejemplos de esta sección usan el Start método para iniciar un archivo ejecutable denominado Write500Lines.exe. El ejemplo siguiente contiene su código fuente.
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.
En el ejemplo siguiente se muestra cómo leer desde una secuencia redirigida y esperar a que el proceso secundario salga. En el ejemplo se evita una condición de interbloqueo llamando a p.StandardOutput.ReadToEnd
antes de p.WaitForExit
. Una condición de interbloqueo puede dar lugar si el proceso primario llama p.WaitForExit
antes p.StandardOutput.ReadToEnd
y el proceso secundario escribe suficiente texto para rellenar la secuencia redirigida. El proceso primario esperaría indefinidamente para que se cierre el proceso secundario. El proceso secundario esperaría indefinidamente para que el elemento primario lea de la secuencia completa 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%
' '
Hay un problema similar al leer todo el texto de los flujos de error estándar y de salida estándar. En el ejemplo siguiente se realiza una operación de lectura en ambos flujos. Evita la condición de interbloqueo realizando operaciones de lectura asincrónicas en la StandardError secuencia. Una condición de interbloqueo da como resultado si el proceso primario llama p.StandardOutput.ReadToEnd
seguido de p.StandardError.ReadToEnd
y el proceso secundario escribe suficiente texto para rellenar su flujo de errores. El proceso primario esperaría indefinidamente para que el proceso secundario cierre su StandardOutput secuencia. El proceso secundario esperaría indefinidamente para que el elemento primario lea de la secuencia completa 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.
Puede usar operaciones de lectura asincrónicas para evitar estas dependencias y su potencial de interbloqueo. Como alternativa, puede evitar la condición de interbloqueo creando dos subprocesos y leyendo la salida de cada secuencia en un subproceso independiente.