Process.StandardOutput Właściwość

Definicja

Pobiera strumień używany do odczytywania tekstowych danych wyjściowych aplikacji.

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

Wartość właściwości

StreamReader

Element StreamReader , który może służyć do odczytywania standardowego strumienia wyjściowego aplikacji.

Atrybuty

Wyjątki

Strumień StandardOutput nie został zdefiniowany na potrzeby przekierowania. Upewnij się, że RedirectStandardOutput true ustawiono wartość i UseShellExecute ustawiono wartość false.

-lub-

Strumień StandardOutput został otwarty dla operacji odczytu asynchronicznego za pomocą polecenia BeginOutputReadLine().

Przykłady

Poniższy przykład uruchamia polecenie ipconfig.exe i przekierowuje standardowe dane wyjściowe do okna konsoli przykładu.

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

Uwagi

Process Gdy tekst jest zapisywany w standardowym strumieniu, tekst jest zwykle wyświetlany w konsoli programu . Przekierowując StandardOutput strumień, można manipulować lub pomijać dane wyjściowe procesu. Na przykład możesz filtrować tekst, formatować go inaczej lub zapisywać dane wyjściowe zarówno w konsoli, jak i wyznaczonym pliku dziennika.

Uwaga

Aby użyć StandardOutputpolecenia , musisz ustawić wartość ProcessStartInfo.UseShellExecute false, a musisz ustawić wartość ProcessStartInfo.RedirectStandardOutput true. W przeciwnym razie odczyt strumienia StandardOutput zgłasza wyjątek.

Przekierowany StandardOutput strumień można odczytywać synchronicznie lub asynchronicznie. Metody takie jak Read, ReadLinei ReadToEnd wykonują synchroniczne operacje odczytu na strumieniu wyjściowym procesu. Te synchroniczne operacje odczytu nie zakończą się, dopóki skojarzone Process operacje zapisu do strumienia StandardOutput lub nie zamkną strumienia.

BeginOutputReadLine Natomiast uruchamia operacje odczytu asynchronicznego w strumieniuStandardOutput. Ta metoda umożliwia wyznaczoną procedurę obsługi zdarzeń dla danych wyjściowych strumienia i natychmiast powraca do obiekt wywołujący, co może wykonać inną pracę, gdy dane wyjściowe strumienia są kierowane do programu obsługi zdarzeń.

Synchroniczne operacje odczytu powodują zależność między odczytem wywołującym ze StandardOutput strumienia a procesem podrzędnym zapisywania w tym strumieniu. Te zależności mogą spowodować zakleszczenie warunków. Gdy obiekt wywołujący odczytuje z przekierowanego strumienia procesu podrzędnego, jest on zależny od elementu podrzędnego. Obiekt wywołujący czeka na operację odczytu, dopóki element podrzędny nie zapisze strumienia lub zamknie strumień. Gdy proces podrzędny zapisuje wystarczająco dużo danych, aby wypełnić przekierowany strumień, jest zależny od elementu nadrzędnego. Proces podrzędny czeka na następną operację zapisu, dopóki element nadrzędny nie odczytuje całego strumienia lub zamknie strumień. Warunek zakleszczenia wynika, gdy obiekt wywołujący i proces podrzędny czekają na siebie, aby ukończyć operację, i żaden z nich nie może kontynuować. Można uniknąć zakleszczenia, oceniając zależności między obiektem wywołującym a procesem podrzędnym.

W dwóch ostatnich przykładach w tej sekcji użyto Start metody , aby uruchomić plik wykonywalny o nazwie Write500Lines.exe. Poniższy przykład zawiera kod źródłowy.

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.

W poniższym przykładzie pokazano, jak odczytać z przekierowanego strumienia i poczekać na zakończenie procesu podrzędnego. W przykładzie unika się warunku zakleszczenia przez wywołanie polecenia przed p.WaitForExit.p.StandardOutput.ReadToEnd Warunek zakleszczenia może spowodować, że proces nadrzędny wywołuje p.WaitForExit proces przed p.StandardOutput.ReadToEnd , a proces podrzędny zapisuje wystarczającą ilość tekstu, aby wypełnić przekierowany strumień. Proces nadrzędny będzie czekać na zakończenie procesu podrzędnego przez czas nieokreślony. Proces podrzędny będzie czekał na czas nieokreślony, aby element nadrzędny odczytał z pełnego StandardOutput strumienia.

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

Podczas odczytywania całego tekstu z standardowych danych wyjściowych i standardowych strumieni błędów występuje podobny problem. Poniższy przykład wykonuje operację odczytu w obu strumieniach. Pozwala uniknąć stanu zakleszczenia, wykonując operacje odczytu asynchronicznego w strumieniu StandardError . Warunek zakleszczenia powoduje, że po wywołaniu p.StandardOutput.ReadToEnd p.StandardError.ReadToEnd procesu nadrzędnego następuje, a proces podrzędny zapisuje wystarczającą ilość tekstu, aby wypełnić strumień błędu. Proces nadrzędny będzie czekać bezterminowo, aż proces podrzędny zamknie strumień StandardOutput . Proces podrzędny będzie czekał na czas nieokreślony, aby element nadrzędny odczytał z pełnego StandardError strumienia.

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.

Możesz użyć asynchronicznych operacji odczytu, aby uniknąć tych zależności i ich potencjału zakleszczenia. Alternatywnie można uniknąć stanu zakleszczenia, tworząc dwa wątki i odczytując dane wyjściowe każdego strumienia w osobnym wątku.

Uwaga

Nie można mieszać asynchronicznych i synchronicznych operacji odczytu na przekierowanym strumieniu. Po otwarciu przekierowanego strumienia elementu Process w trybie asynchronicznym lub synchronicznym wszystkie dalsze operacje odczytu na tym strumieniu muszą być w tym samym trybie. Na przykład nie należy wykonywać BeginOutputReadLine wywołania do ReadLine strumienia StandardOutput ani odwrotnie. Można jednak odczytywać dwa różne strumienie w różnych trybach. Na przykład możesz wywołać wywołanie BeginOutputReadLine strumieniaStandardError, a następnie wywołać goReadLine.

Dotyczy

Zobacz też