Process.StandardOutput 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 una secuencia usada para leer la salida de texto de la aplicación.
public:
property System::IO::StreamReader ^ StandardOutput { System::IO::StreamReader ^ get(); };
public System.IO.StreamReader StandardOutput { get; }
[System.ComponentModel.Browsable(false)]
public System.IO.StreamReader StandardOutput { get; }
member this.StandardOutput : System.IO.StreamReader
[<System.ComponentModel.Browsable(false)>]
member this.StandardOutput : System.IO.StreamReader
Public ReadOnly Property StandardOutput As StreamReader
Valor de propiedad
StreamReader que puede usarse para leer la secuencia de salida estándar de la aplicación.
- Atributos
Excepciones
La secuencia StandardOutput no se ha definido para redirección; asegúrese de que RedirectStandardOutput se establece en true
y UseShellExecute que se establece en false
.
o bien
La secuencia StandardOutput se ha abierto para operaciones de lectura asincrónicas con BeginOutputReadLine().
Ejemplos
En el ejemplo siguiente se ejecuta el comando ipconfig.exe y se redirige su salida estándar a la ventana de la consola del ejemplo.
using namespace System;
using namespace System::IO;
using namespace System::Diagnostics;
int main()
{
Process^ process = gcnew Process();
process->StartInfo->FileName = "ipconfig.exe";
process->StartInfo->UseShellExecute = false;
process->StartInfo->RedirectStandardOutput = true;
process->Start();
// Synchronously read the standard output of the spawned process->
StreamReader^ reader = process->StandardOutput;
String^ output = reader->ReadToEnd();
// Write the redirected output to this application's window.
Console::WriteLine(output);
process->WaitForExit();
process->Close();
Console::WriteLine("\n\nPress any key to exit");
Console::ReadLine();
return 0;
}
using System;
using System.IO;
using System.Diagnostics;
class StandardOutputExample
{
public static void Main()
{
using (Process process = new Process())
{
process.StartInfo.FileName = "ipconfig.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
// Synchronously read the standard output of the spawned process.
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();
// Write the redirected output to this application's window.
Console.WriteLine(output);
process.WaitForExit();
}
Console.WriteLine("\n\nPress any key to exit.");
Console.ReadLine();
}
}
Imports System.IO
Imports System.Diagnostics
Module Module1
Sub Main()
Using process As New Process()
process.StartInfo.FileName = "ipconfig.exe"
process.StartInfo.UseShellExecute = False
process.StartInfo.RedirectStandardOutput = True
process.Start()
' Synchronously read the standard output of the spawned process.
Dim reader As StreamReader = process.StandardOutput
Dim output As String = reader.ReadToEnd()
Console.WriteLine(output)
process.WaitForExit()
End Using
Console.WriteLine(Environment.NewLine + Environment.NewLine + "Press any key to exit.")
Console.ReadLine()
End Sub
End Module
Comentarios
Cuando un Process objeto escribe texto en su secuencia estándar, ese texto se muestra normalmente en la consola. Al 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
Para usar StandardOutput, debe establecer en ProcessStartInfo.UseShellExecutefalse
y debe establecer en ProcessStartInfo.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 para la salida del flujo y vuelve inmediatamente al autor de la llamada, que puede realizar otro trabajo mientras la salida del flujo se dirige al controlador de eventos.
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 dar lugar a 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 en 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 en 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.
Nota
No se pueden mezclar operaciones de lectura asincrónicas y sincrónicas en una secuencia redirigida. Una vez que el flujo redirigido de se Process abre en modo asincrónico o sincrónico, todas las operaciones de lectura adicionales de esa secuencia deben estar en el mismo modo. Por ejemplo, no siga con BeginOutputReadLine una llamada a ReadLine en la StandardOutput secuencia o viceversa. Sin embargo, puede leer dos secuencias diferentes en modos diferentes. Por ejemplo, puede llamar BeginOutputReadLine a y, a continuación, llamar a ReadLine para la StandardError secuencia.