Process.StandardOutput Vlastnost

Definice

Získá datový proud používaný 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

To StreamReader lze použít ke čtení standardního výstupního datového proudu aplikace.

Atributy

Výjimky

Datový StandardOutput proud nebyl definován pro přesměrování; ujistěte RedirectStandardOutput se, že je nastavená true na hodnotu a UseShellExecute je nastavena na falsehodnotu .

nebo

Datový StandardOutput proud byl otevřen pro asynchronní operace čtení s BeginOutputReadLine().

Příklady

Následující příklad spustí příkaz ipconfig.exe a přesměruje jeho standardní výstup do okna konzoly příkladu.

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();
    }
}
module ProcessStandardOutput

open System.Diagnostics

use proc = new Process()
proc.StartInfo.FileName <- "ipconfig.exe"
proc.StartInfo.UseShellExecute <- false
proc.StartInfo.RedirectStandardOutput <- true
proc.Start() |> ignore

// Synchronously read the standard output of the spawned process.
let reader = proc.StandardOutput
let output = reader.ReadToEnd()

// Write the redirected output to this application's window.
printfn $"{output}"

proc.WaitForExit()

printfn "\n\nPress any key to exit."
stdin.ReadLine() |> ignore
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

Process Když zapíše text do standardního datového proudu, obvykle se tento text zobrazí v konzole. Přesměrováním datového StandardOutput proudu můžete manipulovat nebo potlačit výstup procesu. Můžete například filtrovat text, formátovat ho jinak nebo zapisovat výstup do konzoly i určeného souboru protokolu.

Note

Chcete-li použít StandardOutput, musíte nastavit ProcessStartInfo.UseShellExecute , falsea musíte nastavit ProcessStartInfo.RedirectStandardOutput na true. V opačném případě při čtení z datového StandardOutput proudu dojde k výjimce.

Přesměrovaný StandardOutput stream je možné číst synchronně nebo asynchronně. Metody, jako Readje , ReadLinea ReadToEnd provádět synchronní operace čtení ve výstupním datovém proudu procesu. Tyto synchronní operace čtení se nedokončí, dokud přidružené Process zápisy do jeho StandardOutput datového proudu nebo nezavře datový proud.

Naproti tomu BeginOutputReadLine spouští asynchronní operace čtení ve streamu StandardOutput . Tato metoda umožňuje určenou obslužnou rutinu události pro výstup streamu a okamžitě se vrátí volajícímu, který může provádět další práci, zatímco výstup streamu je směrován na obslužnou rutinu události.

Synchronní operace čtení představují závislost mezi volajícím čtením z datového StandardOutput proudu a podřízeným procesem zápisu do tohoto datového proudu. Tyto závislosti můžou vést k zablokování podmínek. Když volající přečte z přesměrovaného datového proudu podřízeného procesu, závisí na podřízené sadě. Volající počká na operaci čtení, dokud podřízený zápis do datového proudu 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é sadě. Podřízený proces čeká na další operaci zápisu, dokud nadřazený objekt nepřečte z úplného datového proudu nebo datový proud zavře. Podmínka vzájemného zablokování způsobí, že volající a podřízený proces čekají na sebe, aby se dokončila operace, a ani jeden z nich nemůže pokračovat. 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ázvem Write500Lines.exe. Následující příklad obsahuje zdrojový kód.

using System;

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:
//      Line 1 of 500 written: 0,20%
//      Line 2 of 500 written: 0,40%
//      Line 3 of 500 written: 0,60%
//      ...
//      Line 498 of 500 written: 99,60%
//      Line 499 of 500 written: 99,80%
//      Line 500 of 500 written: 100,00%
//
//      Successfully wrote 500 lines.
module Write500Lines

for i in 1. .. 500. do
    printfn $"Line {i} of 500 written: {i/500.:P2}";

eprintfn "Successfully wrote 500 lines.";
// The example displays the following output:
//      Line 1 of 500 written: 0,20%
//      Line 2 of 500 written: 0,40%
//      Line 3 of 500 written: 0,60%
//      ...
//      Line 498 of 500 written: 99,60%
//      Line 499 of 500 written: 99,80%
//      Line 500 of 500 written: 100,00%
//      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:
'      Line 1 of 500 written 0,20%
'      Line 2 of 500 written: 0,40%
'      Line 3 of 500 written: 0,60%
'      ...
'      Line 498 of 500 written: 99,60%
'      Line 499 of 500 written: 99,80%
'      Line 500 of 500 written: 100,00%
'
'      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. Příklad se vyhne stavu vzájemného zablokování voláním p.StandardOutput.ReadToEnd před p.WaitForExit. Podmínka zablokování může vést k tomu, že 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 po neomezenou dobu čekal, než se podřízený proces ukončí. Podřízený proces počká neomezeně dlouho, než se nadřazený objekt přečte 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:
//      'ritten: 99,80%
//      Line 500 of 500 written: 100,00%
//      '
module STDOutputSync

open System.Diagnostics

let p = new Process()
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardOutput <- true
p.StartInfo.FileName <- "Write500Lines.exe"
p.Start() |> ignore

// To avoid deadlocks, always read the output stream first and then wait.
let output = p.StandardOutput.ReadToEnd()
p.WaitForExit()

printfn $"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:
//      'ritten: 99,80%
//      Line 500 of 500 written: 100,00%
//      '
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:
'      'ritten: 99,80%
'      Line 500 of 500 written: 100,00%
'      '

Při čtení veškerého textu ze standardního i standardního datového proudu chyb dochází k podobnému problému. Následující příklad provádí operaci čtení v obou datových proudech. Vyhne se konfliktu vzájemného zablokování provedením asynchronních operací čtení ve streamu StandardError . Podmínka zablokování je výsledkem, pokud nadřazený proces volá p.StandardOutput.ReadToEnd a p.StandardError.ReadToEnd podřízený proces zapíše dostatek textu k vyplnění jeho chybového streamu. Nadřazený proces by počkal na neomezenou dobu, než podřízený proces zavře jeho StandardOutput datový proud. Podřízený proces počká neomezeně dlouho, než se nadřazený objekt přečte 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:
//      'ritten: 99,80%
//      Line 500 of 500 written: 100,00%
//      '
//
//      Error stream: Successfully wrote 500 lines.
module STDOutputAsync

open System.Diagnostics

let p = new Process()
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardOutput <- true
let mutable eOut = ""
p.StartInfo.RedirectStandardError <- true
p.ErrorDataReceived.AddHandler(DataReceivedEventHandler(fun sender e -> eOut <- eOut + e.Data))

p.StartInfo.FileName <- "Write500Lines.exe"
p.Start() |> ignore

// To avoid deadlocks, use an asynchronous read operation on at least one of the streams.
p.BeginErrorReadLine()
let output = p.StandardOutput.ReadToEnd()
p.WaitForExit()

printfn $"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'"
printfn $"\nError stream: {eOut}"
// The example displays the following output:
//      The last 50 characters in the output stream are:
//      'ritten: 99,80%
//      Line 500 of 500 written: 100,00%
//      '
//
//      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:
'      'ritten: 99,80%
'      Line 500 of 500 written: 100,00%
'      '
'
'      Error stream: Successfully wrote 500 lines.

Pomocí asynchronních operací čtení se můžete těmto závislostem a jejich potenciálnímu zablokování vyhnout. Případně se můžete vyhnout konfliktu vzájemného zablokování vytvořením dvou vláken a čtením výstupu každého datového proudu v samostatném vlákně.

Note

Asynchronní a synchronní operace čtení u přesměrovaného datového proudu nelze kombinovat. Po otevření přesměrovaného streamu Process v asynchronním nebo synchronním režimu musí být všechny další operace čtení v daném datovém proudu ve stejném režimu. Například nespočítejte BeginOutputReadLine s voláním ReadLine do datového StandardOutput proudu nebo naopak. Můžete ale číst dva různé streamy v různých režimech. Můžete například volat BeginOutputReadLine a volat ReadLine pro StandardError stream.

Platí pro

Viz také