다음을 통해 공유


Process.StandardOutput 속성

정의

애플리케이션의 텍스트 출력을 읽는 데 사용되는 스트림을 가져옵니다.

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

속성 값

애플리케이션의 표준 출력 스트림을 읽는 데 사용할 수 있는 StreamReader입니다.

특성

예외

StandardOutput 스트림이 리디렉션에 대해 정의되지 않았습니다. RedirectStandardOutputtrue로 설정되고 UseShellExecutefalse로 설정되어 있는지 확인하세요.

또는

StandardOutput 스트림이 BeginOutputReadLine()을 사용한 비동기 읽기 작업을 위해 열려 있습니다.

예제

다음 예제에서는 ipconfig.exe 명령을 실행하고 표준 출력을 예제의 콘솔 창으로 리디렉션합니다.

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

설명

Process 표준 스트림에 텍스트를 쓸 때 해당 텍스트는 일반적으로 콘솔에 표시됩니다. 스트림을 StandardOutput 리디렉션하여 프로세스의 출력을 조작하거나 표시하지 않을 수 있습니다. 예를 들어 텍스트를 필터링하거나, 다르게 서식을 지정하거나, 콘솔과 지정된 로그 파일 모두에 출력을 쓸 수 있습니다.

참고

를 사용StandardOutput하려면 를 로 false설정 ProcessStartInfo.UseShellExecute 해야 하며 를 로 true설정 ProcessStartInfo.RedirectStandardOutput 해야 합니다. 그렇지 않으면 스트림에서 읽는 StandardOutput 경우 예외가 throw됩니다.

리디렉션된 스트림은 StandardOutput 동기적으로 또는 비동기적으로 읽을 수 있습니다. Read, ReadLine, 등의 ReadToEnd 메서드는 프로세스의 출력 스트림에서 동기 읽기 작업을 수행합니다. 이러한 동기 읽기 작업은 연결된 Process 가 스트림 StandardOutput 에 쓰거나 스트림을 닫을 때까지 완료되지 않습니다.

반면, 는 BeginOutputReadLine 스트림에서 StandardOutput 비동기 읽기 작업을 시작합니다. 이 메서드는 스트림 출력에 대해 지정된 이벤트 처리기를 사용하도록 설정하고 즉시 호출자에게 반환되며, 이 호출자는 스트림 출력이 이벤트 처리기로 전달되는 동안 다른 작업을 수행할 수 있습니다.

동기 읽기 작업은 스트림에서 읽는 호출자와 해당 스트림에 StandardOutput 쓰는 자식 프로세스 간에 종속성을 도입합니다. 이러한 종속성으로 인해 교착 상태가 발생할 수 있습니다. 호출자가 자식 프로세스의 리디렉션된 스트림에서 읽을 때 자식에 따라 달라집니다. 호출자는 자식이 스트림에 쓰거나 스트림을 닫을 때까지 읽기 작업을 기다립니다. 자식 프로세스가 리디렉션된 스트림을 채우기에 충분한 데이터를 작성하면 부모에 따라 달라집니다. 자식 프로세스는 부모가 전체 스트림에서 읽거나 스트림을 닫을 때까지 다음 쓰기 작업을 기다립니다. 교착 상태 조건은 호출자와 자식 프로세스가 작업을 완료하기 위해 서로 대기할 때 발생하며 둘 다 진행할 수 없습니다. 호출자와 자식 프로세스 간의 종속성을 평가하여 교착 상태를 방지할 수 있습니다.

이 섹션의 마지막 두 예제에서는 메서드를 Start 사용하여 Write500Lines.exe이라는 실행 파일을 시작합니다. 다음 예제에는 소스 코드가 포함되어 있습니다.

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.

다음 예제에서는 리디렉션된 스트림에서 읽고 자식 프로세스가 종료될 때까지 기다리는 방법을 보여줍니다. 이 예제에서는 앞에 p.WaitForExit를 호출 p.StandardOutput.ReadToEnd 하여 교착 상태 조건을 방지합니다. 부모 프로세스가 이전에 p.StandardOutput.ReadToEnd 를 호출 p.WaitForExit 하고 자식 프로세스가 리디렉션된 스트림을 채우기에 충분한 텍스트를 작성하는 경우 교착 상태 조건이 발생할 수 있습니다. 부모 프로세스는 자식 프로세스가 종료될 때까지 무기한 대기합니다. 자식 프로세스는 부모가 전체 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%
'      '

표준 출력 및 표준 오류 스트림 모두에서 모든 텍스트를 읽을 때도 비슷한 문제가 있습니다. 다음 예제에서는 두 스트림에서 읽기 작업을 수행합니다. 스트림에서 비동기 읽기 작업을 수행하여 교착 상태를 방지합니다 StandardError . 교착 상태 조건은 부모 프로세스가 뒤에 p.StandardError.ReadToEnd 를 호출 p.StandardOutput.ReadToEnd 하고 자식 프로세스가 오류 스트림을 채우기에 충분한 텍스트를 작성하는 경우 발생합니다. 부모 프로세스는 자식 프로세스가 스트림을 닫 StandardOutput 을 때까지 무기한 대기합니다. 자식 프로세스는 부모가 전체 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.

비동기 읽기 작업을 사용하여 이러한 종속성과 교착 상태 가능성을 방지할 수 있습니다. 또는 두 개의 스레드를 만들고 별도의 스레드에서 각 스트림의 출력을 읽어 교착 상태를 방지할 수 있습니다.

참고

리디렉션된 스트림에서는 비동기 및 동기 읽기 작업을 혼합할 수 없습니다. 리디렉션된 스트림 Process 이 비동기 또는 동기 모드로 열리면 해당 스트림에 대한 모든 추가 읽기 작업이 동일한 모드에 있어야 합니다. 예를 들어 스트림에서 에 대한 StandardOutput 호출 ReadLine 을 따르지 BeginOutputReadLine 않거나 그 반대의 경우도 마찬가지입니다. 그러나 서로 다른 모드에서 두 개의 서로 다른 스트림을 읽을 수 있습니다. 예를 들어 를 호출 BeginOutputReadLine 한 다음 스트림을 호출 ReadLineStandardError 수 있습니다.

적용 대상

추가 정보