Process.StandardOutput 屬性
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
取得用來讀取應用程式文字輸出的資料流。
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.UseShellExecute 為 false
,而且必須設定 ProcessStartInfo.RedirectStandardOutput 為 true
。 否則,從 StandardOutput 資料流程讀取會擲回例外狀況。
重新導向 StandardOutput 資料流程可以同步或非同步讀取。 、 ReadLine 和 ReadToEnd 等 Read 方法會在進程的輸出資料流程上執行同步讀取作業。 這些同步讀取作業在相關聯的 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 資料流程,然後呼叫 ReadLine StandardError 。