Process.StandardOutput Vlastnost
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Získá datový proud, který se používá ke čtení textového výstupu aplikace.
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
Hodnota vlastnosti
Objekt , StreamReader který lze použít ke čtení standardního výstupního streamu aplikace.
- Atributy
Výjimky
Datový StandardOutput proud nebyl definován pro přesměrování. Ujistěte se, že RedirectStandardOutput je nastavená hodnota true
a UseShellExecute nastavená na false
hodnotu .
-nebo-
Datový StandardOutput proud byl otevřen pro asynchronní operace čtení pomocí BeginOutputReadLine().
Příklady
Následující příklad spustí příkaz ipconfig.exe a přesměruje jeho standardní výstup do okna konzoly v příkladu.
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
Poznámky
Když objekt Process zapisuje text do standardního streamu, obvykle se tento text zobrazí v konzole nástroje . Přesměrováním datového StandardOutput proudu můžete manipulovat nebo potlačit výstup procesu. Můžete například filtrovat text, jinak ho formátovat nebo zapsat výstup do konzoly a určeného souboru protokolu.
Poznámka
Pokud chcete použít StandardOutput, musíte nastavit ProcessStartInfo.UseShellExecute na false
a ProcessStartInfo.RedirectStandardOutput pak na true
. V opačném případě čtení ze streamu StandardOutput vyvolá výjimku.
Přesměrovaný StandardOutput datový proud lze číst synchronně nebo asynchronně. Metody jako Read, ReadLinea ReadToEnd provádějí synchronní operace čtení na výstupním datovém proudu procesu. Tyto synchronní operace čtení se nedokončí, dokud přidružený Process datový proud nezapíše nebo StandardOutput neukončí datový proud.
Naproti tomu BeginOutputReadLine spustí asynchronní operace čtení u datového StandardOutput proudu. Tato metoda povolí určenou obslužnou rutinu události pro výstup datového proudu a okamžitě se vrátí volajícímu, který může provést jinou práci, zatímco výstup datového proudu je směrován na obslužnou rutinu události.
Synchronní operace čtení představují závislost mezi volajícím, který čte z datového proudu, a podřízeným procesem, který do tohoto datového StandardOutput proudu zapisuje. Tyto závislosti můžou vést k podmínkám vzájemného zablokování. Když volající čte z přesměrovaného datového proudu podřízeného procesu, závisí to na podřízené sadě. Volající počká na operaci čtení, dokud podřízený datový proud nezapíše nebo datový proud nezavře. Když podřízený proces zapíše dostatek dat k vyplnění přesměrovaného datového proudu, závisí na nadřazené. Podřízený proces čeká na další operaci zápisu, dokud nadřazený datový proud nepřečte z úplného datového proudu nebo datový proud nezavře. Výsledkem konfliktu vzájemného zablokování je, že volající a podřízený proces čekají na dokončení operace a nemůže pokračovat. Vzájemnému zablokování se můžete vyhnout vyhodnocením závislostí mezi volajícím a podřízeným procesem.
Poslední dva příklady v této části používají metodu Start ke spuštění spustitelného souboru s názvemWrite500Lines.exe. Následující příklad obsahuje jeho zdrojový kód.
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.
Následující příklad ukazuje, jak číst z přesměrovaného datového proudu a čekat na ukončení podřízeného procesu. V příkladu se vyhneme konfliktu vzájemného zablokování voláním p.StandardOutput.ReadToEnd
metody před p.WaitForExit
. Podmínka vzájemného zablokování může být výsledkem, pokud nadřazený proces volá p.WaitForExit
před p.StandardOutput.ReadToEnd
a podřízený proces zapíše dostatek textu k vyplnění přesměrovaného datového proudu. Nadřazený proces by čekal neurčitou dobu na ukončení podřízeného procesu. Podřízený proces by po neomezenou dobu čekal na načtení nadřazeného datového proudu z úplného StandardOutput datového proudu.
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%
' '
K podobnému problému dochází při čtení veškerého textu ze standardního výstupního i standardního chybového proudu. Následující příklad provede operaci čtení v obou datových proudech. Vyhne se konfliktu vzájemného zablokování prováděním asynchronních operací čtení datového StandardError proudu. Výsledkem konfliktu vzájemného zablokování je volání p.StandardOutput.ReadToEnd
nadřazeného procesu, po p.StandardError.ReadToEnd
kterém následuje a podřízený proces zapíše dostatečný text, aby vyplnil svůj datový proud chyb. Nadřazený proces bude čekat neomezeně dlouho, než podřízený proces zavře svůj StandardOutput datový proud. Podřízený proces by po neomezenou dobu čekal na načtení nadřazeného datového proudu z úplného StandardError datového proudu.
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.
Pomocí asynchronních operací čtení se můžete těmto závislostem a jejich potenciálu vzájemného zablokování vyhnout. Případně se můžete konfliktu vzájemného zablokování vyhnout vytvořením dvou vláken a přečtením výstupu každého datového proudu v samostatném vlákně.
Poznámka
U přesměrovaného datového proudu nelze kombinovat asynchronní a synchronní operace čtení. Po otevření přesměrovaného datového proudu v asynchronním nebo synchronním režimu musí být všechny další operace čtení u tohoto datového Process proudu ve stejném režimu. Nesledujte BeginOutputReadLine například voláním ReadLine ve streamu StandardOutput nebo naopak. Můžete ale číst dva různé datové proudy v různých režimech. Můžete například volat BeginOutputReadLine a pak volat ReadLine datový StandardError proud.