Process.BeginErrorReadLine 方法

定義

在應用程式的重新導向 StandardError 數據流上開始異步讀取作業。

public:
 void BeginErrorReadLine();
[System.Runtime.InteropServices.ComVisible(false)]
public void BeginErrorReadLine();
public void BeginErrorReadLine();
[<System.Runtime.InteropServices.ComVisible(false)>]
member this.BeginErrorReadLine : unit -> unit
member this.BeginErrorReadLine : unit -> unit
Public Sub BeginErrorReadLine ()
屬性

例外狀況

IsEditable 屬性為 true。

-或-

串流中已經進行 StandardError 非同步讀取操作。

-或-

StandardError該串流被同步讀取操作所使用。

範例

以下範例使用 net view 指令來列出遠端電腦上的可用網路資源。 使用者以命令列參數的方式提供目標電腦名稱。 使用者也可以提供錯誤輸出的檔名。 範例會收集 net 指令的輸出,等待程序結束後,將輸出結果寫入主控台。 若使用者提供可選錯誤檔案,範例會將錯誤寫入該檔案。

// Define the namespaces used by this sample.
using System;
using System.Text;
using System.Globalization;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.ComponentModel;

namespace ProcessAsyncStreamSamples
{

    class ProcessNetStreamRedirection
    {
        // Define static variables shared by class methods.
        private static StreamWriter streamError =null;
        private static String netErrorFile = "";
        private static StringBuilder netOutput = null;
        private static bool errorRedirect = false;
        private static bool errorsWritten = false;

        public static void RedirectNetCommandStreams()
        {
            String netArguments;
            Process netProcess;

            // Get the input computer name.
            Console.WriteLine("Enter the computer name for the net view command:");
            netArguments = Console.ReadLine().ToUpper(CultureInfo.InvariantCulture);
            if (String.IsNullOrEmpty(netArguments))
            {
                // Default to the help command if there is not an input argument.
                netArguments = "/?";
            }

            // Check if errors should be redirected to a file.
            errorsWritten = false;
            Console.WriteLine("Enter a fully qualified path to an error log file");
            Console.WriteLine("  or just press Enter to write errors to console:");
            netErrorFile = Console.ReadLine().ToUpper(CultureInfo.InvariantCulture);
            if (!String.IsNullOrEmpty(netErrorFile))
            {
                errorRedirect = true;
            }

            // Note that at this point, netArguments and netErrorFile
            // are set with user input.  If the user did not specify
            // an error file, then errorRedirect is set to false.

            // Initialize the process and its StartInfo properties.
            netProcess = new Process();
            netProcess.StartInfo.FileName = "Net.exe";

            // Build the net command argument list.
            netProcess.StartInfo.Arguments = String.Format("view {0}",
                netArguments);

            // Set UseShellExecute to false for redirection.
            netProcess.StartInfo.UseShellExecute = false;

            // Redirect the standard output of the net command.
            // This stream is read asynchronously using an event handler.
            netProcess.StartInfo.RedirectStandardOutput = true;
            netProcess.OutputDataReceived += new DataReceivedEventHandler(NetOutputDataHandler);
            netOutput = new StringBuilder();

            if (errorRedirect)
            {
                // Redirect the error output of the net command.
                netProcess.StartInfo.RedirectStandardError = true;
                netProcess.ErrorDataReceived += new DataReceivedEventHandler(NetErrorDataHandler);
            }
            else
            {
                // Do not redirect the error output.
                netProcess.StartInfo.RedirectStandardError = false;
            }

            Console.WriteLine("\nStarting process: net {0}",
                netProcess.StartInfo.Arguments);
            if (errorRedirect)
            {
                Console.WriteLine("Errors will be written to the file {0}",
                    netErrorFile);
            }

            // Start the process.
            netProcess.Start();

            // Start the asynchronous read of the standard output stream.
            netProcess.BeginOutputReadLine();

            if (errorRedirect)
            {
                // Start the asynchronous read of the standard
                // error stream.
                netProcess.BeginErrorReadLine();
            }

            // Let the net command run, collecting the output.
            netProcess.WaitForExit();

            if (streamError != null)
            {
                // Close the error file.
                streamError.Close();
            }
            else
            {
                // Set errorsWritten to false if the stream is not
                // open.   Either there are no errors, or the error
                // file could not be opened.
                errorsWritten = false;
            }

            if (netOutput.Length > 0)
            {
                // If the process wrote more than just
                // white space, write the output to the console.
                Console.WriteLine("\nPublic network shares from net view:\n{0}\n",
                    netOutput);
            }

            if (errorsWritten)
            {
                // Signal that the error file had something
                // written to it.
                String [] errorOutput = File.ReadAllLines(netErrorFile);
                if (errorOutput.Length > 0)
                {
                    Console.WriteLine("\nThe following error output was appended to {0}.",
                        netErrorFile);
                    foreach (String errLine in errorOutput)
                    {
                        Console.WriteLine("  {0}", errLine);
                    }
                }
                Console.WriteLine();
            }

            netProcess.Close();
        }

        private static void NetOutputDataHandler(object sendingProcess,
            DataReceivedEventArgs outLine)
        {
            // Collect the net view command output.
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                // Add the text to the collected output.
                netOutput.Append(Environment.NewLine + "  " + outLine.Data);
            }
        }

        private static void NetErrorDataHandler(object sendingProcess,
            DataReceivedEventArgs errLine)
        {
            // Write the error text to the file if there is something
            // to write and an error file has been specified.

            if (!String.IsNullOrEmpty(errLine.Data))
            {
                if (!errorsWritten)
                {
                    if (streamError == null)
                    {
                        // Open the file.
                        try
                        {
                            streamError = new StreamWriter(netErrorFile, true);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Could not open error file!");
                            Console.WriteLine(e.Message.ToString());
                        }
                    }

                    if (streamError != null)
                    {
                        // Write a header to the file if this is the first
                        // call to the error output handler.
                        streamError.WriteLine();
                        streamError.WriteLine(DateTime.Now.ToString());
                        streamError.WriteLine("Net View error output:");
                    }
                    errorsWritten = true;
                }

                if (streamError != null)
                {
                    // Write redirected errors to the file.
                    streamError.WriteLine(errLine.Data);
                    streamError.Flush();
                }
            }
        }
    }
}
// Define the namespaces used by this sample.
open System
open System.Text
open System.Globalization
open System.IO
open System.Diagnostics

// Define variables shared by functions.
let mutable streamError = Unchecked.defaultof<StreamWriter>
let mutable netErrorFile = ""
let mutable netOutput = StringBuilder()
let mutable errorRedirect = false
let mutable errorsWritten = false

let netOutputDataHandler (sendingProcess: obj) (outLine: DataReceivedEventArgs) =
    // Collect the net view command output.
    if String.IsNullOrEmpty outLine.Data |> not then
        // Add the text to the collected output.
        netOutput.Append(Environment.NewLine + "  " + outLine.Data) |> ignore

let netErrorDataHandler (sendingProcess: obj) (errLine: DataReceivedEventArgs) =
    // Write the error text to the file if there is something
    // to write and an error file has been specified.

    if String.IsNullOrEmpty errLine.Data |> not then
        if not errorsWritten then
            if isNull streamError then
                // Open the file.
                try
                    streamError <- new StreamWriter(netErrorFile, true)
                with e ->
                    printfn "Could not open error file!"
                    printfn $"{e.Message}"

            if isNull streamError |> not then
                // Write a header to the file if this is the first
                // call to the error output handler.
                streamError.WriteLine()
                streamError.WriteLine DateTime.Now
                streamError.WriteLine "Net View error output:"

            errorsWritten <- true

        if isNull streamError |> not then
            // Write redirected errors to the file.
            streamError.WriteLine errLine.Data
            streamError.Flush()


let redirectNetCommandStreams () =
    // Get the input computer name.
    printfn "Enter the computer name for the net view command:"
    let netArguments = stdin.ReadLine().ToUpper CultureInfo.InvariantCulture
    // Default to the help command if there is not an input argument.
    let netArguments =
        if String.IsNullOrEmpty netArguments then
            "/?"
        else
            netArguments

    // Check if errors should be redirected to a file.
    errorsWritten <- false
    printfn "Enter a fully qualified path to an error log file"
    printfn "  or just press Enter to write errors to console:"
    netErrorFile <- stdin.ReadLine().ToUpper CultureInfo.InvariantCulture

    if String.IsNullOrEmpty netErrorFile |> not then
        errorRedirect <- true

    // Note that at this point, netArguments and netErrorFile
    // are set with user input.  If the user did not specify
    // an error file, then errorRedirect is set to false.

    // Initialize the process and its StartInfo properties.
    let netProcess = new Process()
    netProcess.StartInfo.FileName <- "Net.exe"

    // Build the net command argument list.
    netProcess.StartInfo.Arguments <- $"view {netArguments}"

    // Set UseShellExecute to false for redirection.
    netProcess.StartInfo.UseShellExecute <- false

    // Redirect the standard output of the net command.
    // This stream is read asynchronously using an event handler.
    netProcess.StartInfo.RedirectStandardOutput <- true
    netProcess.OutputDataReceived.AddHandler(DataReceivedEventHandler netOutputDataHandler)
    netOutput <- new StringBuilder()

    if errorRedirect then
        // Redirect the error output of the net command.
        netProcess.StartInfo.RedirectStandardError <- true
        netProcess.ErrorDataReceived.AddHandler(DataReceivedEventHandler netErrorDataHandler)
    else
        // Do not redirect the error output.
        netProcess.StartInfo.RedirectStandardError <- false

    printfn $"\nStarting process: net {netProcess.StartInfo.Arguments}"

    if errorRedirect then
        printfn $"Errors will be written to the file {netErrorFile}"

    // Start the process.
    netProcess.Start() |> ignore

    // Start the asynchronous read of the standard output stream.
    netProcess.BeginOutputReadLine()

    if errorRedirect then
        // Start the asynchronous read of the standard error stream.
        netProcess.BeginErrorReadLine()

    // Let the net command run, collecting the output.
    netProcess.WaitForExit()

    if streamError <> null then
        // Close the error file.
        streamError.Close()
    else
        // Set errorsWritten to false if the stream is not
        // open.   Either there are no errors, or the error
        // file could not be opened.
        errorsWritten <- false

    if netOutput.Length > 0 then
        // If the process wrote more than just
        // white space, write the output to the console.
        printfn $"\nPublic network shares from net view:\n{netOutput}\n"

    if errorsWritten then
        // Signal that the error file had something
        // written to it.
        let errorOutput = File.ReadAllLines netErrorFile

        if errorOutput.Length > 0 then
            printfn $"\nThe following error output was appended to {netErrorFile}."

            for errLine in errorOutput do
                printfn $"  {errLine}"

        printfn ""

    netProcess.Close()
' Define the namespaces used by this sample.
Imports System.Text
Imports System.Globalization
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports System.ComponentModel

Namespace ProcessAsyncStreamSamples
   
   Class ProcessAsyncErrorRedirection
      ' Define static variables shared by class methods.
      Private Shared streamError As StreamWriter = Nothing
      Private Shared netErrorFile As String = ""
      Private Shared netOutput As StringBuilder = Nothing
      Private Shared errorRedirect As Boolean = False
      Private Shared errorsWritten As Boolean = False
      
      Public Shared Sub RedirectNetCommandStreams()
         Dim netArguments As String
         Dim netProcess As Process
         
         ' Get the input computer name.
         Console.WriteLine("Enter the computer name for the net view command:")
         netArguments = Console.ReadLine().ToUpper(CultureInfo.InvariantCulture)
         If String.IsNullOrEmpty(netArguments) Then
            ' Default to the help command if there is 
            ' not an input argument.
            netArguments = "/?"
         End If
         
         ' Check if errors should be redirected to a file.
         errorsWritten = False
         Console.WriteLine("Enter a fully qualified path to an error log file")
         Console.WriteLine("  or just press Enter to write errors to console:")
         netErrorFile = Console.ReadLine().ToUpper(CultureInfo.InvariantCulture)
         If Not String.IsNullOrEmpty(netErrorFile) Then
            errorRedirect = True
         End If
         
         ' Note that at this point, netArguments and netErrorFile
         ' are set with user input.  If the user did not specify
         ' an error file, then errorRedirect is set to false.

         ' Initialize the process and its StartInfo properties.
         netProcess = New Process()
         netProcess.StartInfo.FileName = "Net.exe"
         
         ' Build the net command argument list.
         netProcess.StartInfo.Arguments = String.Format("view {0}", _
                                                        netArguments)
         
         ' Set UseShellExecute to false for redirection.
         netProcess.StartInfo.UseShellExecute = False
         
         ' Redirect the standard output of the net command.  
         ' Read the stream asynchronously using an event handler.
         netProcess.StartInfo.RedirectStandardOutput = True
         AddHandler netProcess.OutputDataReceived, _
                            AddressOf NetOutputDataHandler
         netOutput = new StringBuilder()
         
         If errorRedirect Then
            ' Redirect the error output of the net command. 
            netProcess.StartInfo.RedirectStandardError = True
            AddHandler netProcess.ErrorDataReceived, _
                            AddressOf NetErrorDataHandler
         Else
            ' Do not redirect the error output.
            netProcess.StartInfo.RedirectStandardError = False
         End If
         
         Console.WriteLine(ControlChars.Lf + "Starting process: NET {0}", _
                           netProcess.StartInfo.Arguments)
         If errorRedirect Then
            Console.WriteLine("Errors will be written to the file {0}", _
                           netErrorFile)
         End If
         
         ' Start the process.
         netProcess.Start()
         
         ' Start the asynchronous read of the standard output stream.
         netProcess.BeginOutputReadLine()
         
         If errorRedirect Then
            ' Start the asynchronous read of the standard
            ' error stream.
            netProcess.BeginErrorReadLine()
         End If
         
         ' Let the net command run, collecting the output.
         netProcess.WaitForExit()
      
         If Not streamError Is Nothing Then
             ' Close the error file.
             streamError.Close()
         Else 
             ' Set errorsWritten to false if the stream is not
             ' open.   Either there are no errors, or the error
             ' file could not be opened.
             errorsWritten = False
         End If
   
         If netOutput.Length > 0 Then
            ' If the process wrote more than just
            ' white space, write the output to the console.
            Console.WriteLine()
            Console.WriteLine("Public network shares from net view:")
            Console.WriteLine()
            Console.WriteLine(netOutput)
            Console.WriteLine()
         End If
         
         If errorsWritten Then
            ' Signal that the error file had something 
            ' written to it.
            Dim errorOutput As String()
            errorOutput = File.ReadAllLines(netErrorFile)
            If errorOutput.Length > 0 Then

                Console.WriteLine(ControlChars.Lf + _
                    "The following error output was appended to {0}.", _
                    netErrorFile)
                Dim errLine as String
                For Each errLine in errorOutput
                    Console.WriteLine("  {0}", errLine)
                Next
          
                Console.WriteLine()
            End If
         End If
         
         netProcess.Close()
      End Sub 
      
      
      Private Shared Sub NetOutputDataHandler(sendingProcess As Object, _
          outLine As DataReceivedEventArgs)

         ' Collect the net view command output.
         If Not String.IsNullOrEmpty(outLine.Data) Then
            ' Add the text to the collected output.
            netOutput.Append(Environment.NewLine + "  " + outLine.Data)
         End If
      End Sub 
       
      
      Private Shared Sub NetErrorDataHandler(sendingProcess As Object, _
          errLine As DataReceivedEventArgs)

         ' Write the error text to the file if there is something to
         ' write and an error file has been specified.

         If Not String.IsNullOrEmpty(errLine.Data) Then

            If Not errorsWritten Then
                If streamError Is Nothing Then
                    ' Open the file.
                    Try 
                        streamError = New StreamWriter(netErrorFile, true)
                    Catch e As Exception
                        Console.WriteLine("Could not open error file!")
                        Console.WriteLine(e.Message.ToString())
                    End Try
                End If

                If Not streamError Is Nothing Then

                    ' Write a header to the file if this is the first
                    ' call to the error output handler.
                    streamError.WriteLine()
                    streamError.WriteLine(DateTime.Now.ToString())
                    streamError.WriteLine("Net View error output:")

                End If

                errorsWritten = True
            End If
                     
            If Not streamError Is Nothing Then
                  
                ' Write redirected errors to the file.
                streamError.WriteLine(errLine.Data)
                streamError.Flush()
             End If
          End If
      End Sub 
   End Class  
End Namespace

備註

StandardError串流可以同步或非同步讀取。 像 、 ReadLineReadToEnd 等方法Read對程序的錯誤輸出流執行同步讀取操作。 這些同步讀取操作直到相關 Process 寫入者寫入其 StandardError 串流或關閉串流後才會完成。

相較之下,開始 BeginErrorReadLineStandardError 串流進行非同步讀取操作。 此方法啟用指定的事件處理程序處理串流輸出,並立即回傳給呼叫者,呼叫者可在串流輸出導向事件處理程序的同時執行其他工作。

請依照以下步驟對 執行StandardError非同步讀取操作:Process

  1. UseShellExecute 設定為 false

  2. RedirectStandardError 設定為 true

  3. 把你的事件處理程式加入事件。ErrorDataReceived 事件處理器必須與代理簽名相匹配 System.Diagnostics.DataReceivedEventHandler

  4. 啟動 Process

  5. 請呼叫BeginErrorReadLineProcess 此呼叫啟動對 的 StandardError非同步讀取操作。

當非同步讀取操作開始時,事件處理器會在所關聯 Process 的執行者寫入一行文字到其 StandardError 串流時被呼叫。

你可以透過呼叫 CancelErrorRead來取消非同步讀取操作。 讀取操作可由呼叫者或事件處理程序取消。 取消後,你可以再次呼叫 BeginErrorReadLine 以恢復非同步讀取操作。

Note

你不能在重定向的串流上混合非同步與同步讀取操作。 一旦 A Process 的重定向串流以非同步或同步模式開啟,該串流的所有後續讀取操作都必須維持在同一模式下。 例如,不要在直播中 BeginErrorReadLine 接著叫 to ReadLineStandardError ,反之亦然。 不過,你可以在不同模式下讀取兩種不同的串流。 例如,你可以先打電話 BeginErrorReadLine ,然後再打電話 ReadLine 來聽直播 StandardOutput

適用於

另請參閱