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 資料流;請確定已將 RedirectStandardOutput 設為 true,且將 UseShellExecute 設為 false

-或-

已開啟 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,您必須將 設定 ProcessStartInfo.UseShellExecutefalse,而且必須設定 ProcessStartInfo.RedirectStandardOutputtrue。 否則,從 StandardOutput 數據流讀取會擲回例外狀況。

重新導向 StandardOutput 的數據流可以同步或異步讀取。 、 ReadLineRead方法會在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.StandardOutput.ReadToEnd 後面接著 p.StandardError.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 之後,該數據流上的所有進一步讀取作業都必須處於相同的模式。 例如,請勿在BeginOutputReadLine數據流上StandardOutput呼叫 ReadLine ,反之亦然。 不過,您可以在不同的模式中讀取兩個不同的數據流。 例如,您可以呼叫 BeginOutputReadLine 資料流,然後呼叫 ReadLineStandardError

適用於

另請參閱