Teilen über


Process.CancelOutputRead Methode

Definition

Bricht den asynchronen Lesevorgang im umgeleiteten StandardOutput-Stream einer Anwendung ab.

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

Ausnahmen

Der StandardOutput-Stream ist nicht für asynchrone Lesevorgänge aktiviert.

Beispiele

Im folgenden Beispiel wird der Befehl mit vom nmake Benutzer bereitgestellten Argumenten gestartet. Fehler- und Ausgabedatenströme werden asynchron gelesen. die gesammelten Textzeilen werden in der Konsole angezeigt und in eine Protokolldatei geschrieben. Wenn die Befehlsausgabe eine angegebene Anzahl von Zeilen überschreitet, werden die asynchronen Lesevorgänge abgebrochen.

ref class ProcessNMakeStreamRedirection
{
private:
   // Define static variables shared by class methods.
   static StreamWriter^ buildLogStream = nullptr;
   static Mutex^ logMutex = gcnew Mutex;
   static int maxLogLines = 25;
   static int currentLogLines = 0;

public:
   static void RedirectNMakeCommandStreams()
   {
      String^ nmakeArguments = nullptr;
      Process^ nmakeProcess;
      
      // Get the input nmake command-line arguments.
      Console::WriteLine( "Enter the NMake command line arguments (@commandfile or /f makefile, etc):" );
      String^ inputText = Console::ReadLine();
      if (  !String::IsNullOrEmpty( inputText ) )
      {
         nmakeArguments = inputText;
      }

      Console::WriteLine( "Enter max line limit for log file (default is 25):" );
      inputText = Console::ReadLine();
      if (  !String::IsNullOrEmpty( inputText ) )
      {
         if (  !Int32::TryParse( inputText, maxLogLines ) )
         {
            maxLogLines = 25;
         }
      }
      Console::WriteLine( "Output beyond {0} lines will be ignored.",
         maxLogLines.ToString() );
      
      // Initialize the process and its StartInfo properties.
      nmakeProcess = gcnew Process;
      nmakeProcess->StartInfo->FileName = "NMake.exe";
      
      // Build the nmake command argument list.
      if (  !String::IsNullOrEmpty( nmakeArguments ) )
      {
         nmakeProcess->StartInfo->Arguments = nmakeArguments;
      }
      
      // Set UseShellExecute to false for redirection.
      nmakeProcess->StartInfo->UseShellExecute = false;
      
      // Redirect the standard output of the nmake command.  
      // Read the stream asynchronously using an event handler.
      nmakeProcess->StartInfo->RedirectStandardOutput = true;
      nmakeProcess->OutputDataReceived += gcnew DataReceivedEventHandler( NMakeOutputDataHandler );
      
      // Redirect the error output of the nmake command. 
      nmakeProcess->StartInfo->RedirectStandardError = true;
      nmakeProcess->ErrorDataReceived += gcnew DataReceivedEventHandler( NMakeErrorDataHandler );

      logMutex->WaitOne();

      currentLogLines = 0;
      
      // Write a header to the log file.
      String^ buildLogFile = "NmakeCmd.Txt";
      try
      {
         buildLogStream = gcnew StreamWriter( buildLogFile,true );
      }
      catch ( Exception^ e ) 
      {
         Console::WriteLine( "Could not open output file {0}", buildLogFile );
         Console::WriteLine( "Exception = {0}", e->ToString() );
         Console::WriteLine( e->Message->ToString() );

         buildLogStream = nullptr;
      }

      if ( buildLogStream != nullptr )
      {
         Console::WriteLine( "Nmake output logged to {0}", buildLogFile );

         buildLogStream->WriteLine();
         buildLogStream->WriteLine( DateTime::Now.ToString() );
         if (  !String::IsNullOrEmpty( nmakeArguments ) )
         {
            buildLogStream->Write( "Command line = NMake {0}", nmakeArguments );
         }
         else
         {
            buildLogStream->Write( "Command line = Nmake" );
         }
         buildLogStream->WriteLine();
         buildLogStream->Flush();

         logMutex->ReleaseMutex();
         
         // Start the process.
         Console::WriteLine();
         Console::WriteLine( "\nStarting Nmake command" );
         Console::WriteLine();
         nmakeProcess->Start();
         
         // Start the asynchronous read of the output stream.
         nmakeProcess->BeginOutputReadLine();
         
         // Start the asynchronous read of the error stream.
         nmakeProcess->BeginErrorReadLine();
         
         // Let the nmake command run, collecting the output.
         nmakeProcess->WaitForExit();

         nmakeProcess->Close();
         buildLogStream->Close();
         logMutex->Dispose();
      }
   }

private:
   static void NMakeOutputDataHandler( Object^ sendingProcess,
      DataReceivedEventArgs^ outLine )
   {
      // Collect the output, displaying it to the screen and 
      // logging it to the output file.  Cancel the read
      // operation when the maximum line limit is reached.

      if (  !String::IsNullOrEmpty( outLine->Data ) )
      {
         logMutex->WaitOne();

         currentLogLines++;
         if ( currentLogLines > maxLogLines )
         {
            // Display the line to the console.
            // Skip writing the line to the log file.
            Console::WriteLine( "StdOut: {0}", outLine->Data->ToString() );
         }
         else
         if ( currentLogLines == maxLogLines )
         {
            LogToFile( "StdOut", "<Max build log limit reached!>", true );
            
            // Stop reading the output streams.
            Process^ p = dynamic_cast<Process^>(sendingProcess);
            if ( p != nullptr )
            {
               p->CancelOutputRead();
               p->CancelErrorRead();
            }
         }
         else
         {
            // Write the line to the log file.
            LogToFile( "StdOut", outLine->Data, true );
         }
         logMutex->ReleaseMutex();
      }
   }

   static void NMakeErrorDataHandler( Object^ sendingProcess,
      DataReceivedEventArgs^ errLine )
   {
      
      // Collect the error output, displaying it to the screen and 
      // logging it to the output file.  Cancel the error output
      // read operation when the maximum line limit is reached.

      if (  !String::IsNullOrEmpty( errLine->Data ) )
      {
         logMutex->WaitOne();

         currentLogLines++;
         if ( currentLogLines > maxLogLines )
         {
            
            // Display the line to the console.
            // Skip writing the line to the log file.
            Console::WriteLine( "StdErr: {0}", errLine->Data->ToString() );
         }
         else
         if ( currentLogLines == maxLogLines )
         {
            LogToFile( "StdOut", "<Max build log limit reached!>", true );
            
            // Stop reading the output streams.
            Process^ p = dynamic_cast<Process^>(sendingProcess);
            if ( p != nullptr )
            {
               p->CancelOutputRead();
               p->CancelErrorRead();
            }
         }
         else
         {
            // Write the line to the log file.
            LogToFile( "StdErr", errLine->Data, true );
         }
         logMutex->ReleaseMutex();
      }
   }

   static void LogToFile( String^ logPrefix, String^ logText,
      bool echoToConsole )
   {
      // Write the specified line to the log file stream.
      StringBuilder^ logString = gcnew StringBuilder;

      if (  !String::IsNullOrEmpty( logPrefix ) )
      {
         logString->AppendFormat( "{0}> ", logPrefix );
      }

      if (  !String::IsNullOrEmpty( logText ) )
      {
         logString->Append( logText );
      }

      if ( buildLogStream != nullptr )
      {
         buildLogStream->WriteLine(  "[{0}] {1}",
            DateTime::Now.ToString(), logString->ToString() );
         buildLogStream->Flush();
      }

      if ( echoToConsole )
      {
         Console::WriteLine( logString->ToString() );
      }
   }
};
namespace ProcessAsyncStreamSamples
{
    class ProcessNMakeStreamRedirection
    {
        // Define static variables shared by class methods.
        private static StreamWriter buildLogStream =null;
        private static Mutex logMutex = new Mutex();
        private static int maxLogLines = 25;
        private static int currentLogLines = 0;

        public static void RedirectNMakeCommandStreams()
        {
            String nmakeArguments = null;
            Process nmakeProcess;

            // Get the input nmake command-line arguments.
            Console.WriteLine("Enter the NMake command line arguments " +
                "(@commandfile or /f makefile, etc):");
            String inputText = Console.ReadLine();
            if (!String.IsNullOrEmpty(inputText))
            {
                nmakeArguments = inputText;
            }

            Console.WriteLine("Enter max line limit for log file (default is 25):");
            inputText = Console.ReadLine();
            if (!String.IsNullOrEmpty(inputText))
            {
                if (!Int32.TryParse(inputText, out maxLogLines))
                {
                    maxLogLines = 25;
                }
            }
            Console.WriteLine("Output beyond {0} lines will be ignored.",
                maxLogLines);

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

            // Build the nmake command argument list.
            if (!String.IsNullOrEmpty(nmakeArguments))
            {
                nmakeProcess.StartInfo.Arguments = nmakeArguments;
            }

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

            // Redirect the standard output of the nmake command.
            // Read the stream asynchronously using an event handler.
            nmakeProcess.StartInfo.RedirectStandardOutput = true;
            nmakeProcess.OutputDataReceived += new DataReceivedEventHandler(NMakeOutputDataHandler);

            // Redirect the error output of the nmake command.
            nmakeProcess.StartInfo.RedirectStandardError = true;
            nmakeProcess.ErrorDataReceived += new DataReceivedEventHandler(NMakeErrorDataHandler);

            logMutex.WaitOne();

            currentLogLines = 0;

            // Write a header to the log file.
            const String buildLogFile = "NmakeCmd.Txt";
            try
            {
                buildLogStream = new StreamWriter(buildLogFile, true);
            }
            catch (Exception e)
            {
                Console.WriteLine("Could not open output file {0}", buildLogFile);
                Console.WriteLine("Exception = {0}", e.ToString());
                Console.WriteLine(e.Message);

                buildLogStream = null;
            }

            if (buildLogStream != null)
            {
                Console.WriteLine("Nmake output logged to {0}",
                    buildLogFile);

                buildLogStream.WriteLine();
                buildLogStream.WriteLine(DateTime.Now.ToString());
                if (!String.IsNullOrEmpty(nmakeArguments))
                {
                    buildLogStream.Write("Command line = NMake {0}",
                        nmakeArguments);
                }
                else
                {
                    buildLogStream.Write("Command line = Nmake");
                }
                buildLogStream.WriteLine();
                buildLogStream.Flush();

                logMutex.ReleaseMutex();

                // Start the process.
                Console.WriteLine();
                Console.WriteLine("\nStarting Nmake command...");
                Console.WriteLine();
                nmakeProcess.Start();

                // Start the asynchronous read of the error stream.
                nmakeProcess.BeginErrorReadLine();

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

                // Let the nmake command run, collecting the output.
                nmakeProcess.WaitForExit();

                nmakeProcess.Close();
                buildLogStream.Close();
                logMutex.Dispose();
            }
        }

        private static void NMakeOutputDataHandler(object sendingProcess,
            DataReceivedEventArgs outLine)
        {
            // Collect the output, displaying it to the screen and
            // logging it to the output file.  Cancel the read
            // operation when the maximum line limit is reached.

            if (!String.IsNullOrEmpty(outLine.Data))
            {
                logMutex.WaitOne();

                currentLogLines++;
                if (currentLogLines > maxLogLines)
                {
                    // Display the line to the console.
                    // Skip writing the line to the log file.
                    Console.WriteLine("StdOut: {0}", outLine.Data);
                }
                else if (currentLogLines == maxLogLines)
                {
                    LogToFile("StdOut", "<Max build log limit reached!>",
                        true);

                    // Stop reading the output streams.
                    Process p = sendingProcess as Process;
                    if (p != null)
                    {
                        p.CancelOutputRead();
                        p.CancelErrorRead();
                    }
                }
                else
                {
                    // Write the line to the log file.
                    LogToFile("StdOut", outLine.Data, true);
                }
                logMutex.ReleaseMutex();
            }
        }

        private static void NMakeErrorDataHandler(object sendingProcess,
            DataReceivedEventArgs errLine)
        {
            // Collect error output, displaying it to the screen and
            // logging it to the output file.  Cancel the error output
            // read operation when the maximum line limit is reached.

            if (!String.IsNullOrEmpty(errLine.Data))
            {
                logMutex.WaitOne();

                currentLogLines++;
                if (currentLogLines > maxLogLines)
                {
                    // Display the error line to the console.
                    // Skip writing the line to the log file.
                    Console.WriteLine("StdErr: {0}", errLine.Data);
                }
                else if (currentLogLines == maxLogLines)
                {
                    LogToFile("StdErr", "<Max build log limit reached!>",
                        true);

                    // Stop reading the output streams
                    Process p = sendingProcess as Process;
                    if (p != null)
                    {
                        p.CancelErrorRead();
                        p.CancelOutputRead();
                    }
                }
                else
                {
                    // Write the line to the log file.
                    LogToFile("StdErr", errLine.Data, true);
                }

                logMutex.ReleaseMutex();
            }
        }

        private static void LogToFile(String logPrefix,
            String logText, bool echoToConsole)
        {
            // Write the specified line to the log file stream.
            StringBuilder logString = new StringBuilder();

            if (!String.IsNullOrEmpty(logPrefix))
            {
                logString.AppendFormat("{0}> ", logPrefix);
            }

            if (!String.IsNullOrEmpty(logText))
            {
                logString.Append(logText);
            }

            if (buildLogStream != null)
            {
                buildLogStream.WriteLine("[{0}] {1}",
                    DateTime.Now.ToString(), logString.ToString());
                buildLogStream.Flush();
            }

            if (echoToConsole)
            {
                Console.WriteLine(logString.ToString());
            }
        }
    }
}
' Define the namespaces used by this sample.
Imports System.Text
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports System.ComponentModel

Class ProcessNMakeStreamRedirection

   ' Define static variables shared by class methods.
   Private Shared buildLogStream As StreamWriter = Nothing
   Private Shared logMutex As Mutex = New Mutex()
   Private Shared maxLogLines As Integer = 25
   Private Shared currentLogLines As Integer = 0
   
   
   Public Shared Sub RedirectNMakeCommandStreams()
      Dim nmakeArguments As String = Nothing
      Dim nmakeProcess As Process
      
      ' Get the input nmake command-line arguments.
      Console.WriteLine("Enter the NMake command line arguments" + _
          " (@commandfile or /f makefile, etc):")
      Dim inputText As String = Console.ReadLine()
      If Not String.IsNullOrEmpty(inputText) Then
         nmakeArguments = inputText
      End If
      
      Console.WriteLine("Enter max line limit for log file (default is 25):")
      inputText = Console.ReadLine()
      If Not String.IsNullOrEmpty(inputText) Then
         If Not Int32.TryParse(inputText, maxLogLines) Then
            maxLogLines = 25
         End If
      End If
      Console.WriteLine("Output beyond {0} lines will be ignored.", _
          maxLogLines)
      
      ' Initialize the process and its StartInfo properties.
      nmakeProcess = New Process()
      nmakeProcess.StartInfo.FileName = "NMake.exe"
      
      ' Build the nmake command argument list.
      If Not String.IsNullOrEmpty(nmakeArguments) Then
         nmakeProcess.StartInfo.Arguments = nmakeArguments
      End If
      
      ' Set UseShellExecute to false for redirection.
      nmakeProcess.StartInfo.UseShellExecute = False
      
      ' Redirect the standard output of the nmake command.  
      ' Read the stream asynchronously using an event handler.
      nmakeProcess.StartInfo.RedirectStandardOutput = True
      AddHandler nmakeProcess.OutputDataReceived, _
                AddressOf NMakeOutputDataHandler
      
      ' Redirect the error output of the nmake command. 
      nmakeProcess.StartInfo.RedirectStandardError = True
      AddHandler nmakeProcess.ErrorDataReceived, _
                AddressOf NMakeErrorDataHandler

      logMutex.WaitOne()

      currentLogLines = 0
    
      ' Write a header to the log file.
      Const buildLogFile As String = "NmakeCmd.Txt"
      Try 
          buildLogStream = new StreamWriter(buildLogFile, true)
      Catch e As Exception
          Console.WriteLine("Could not open output file {0}", buildLogFile)
          Console.WriteLine("Exception = {0}", e.ToString())
          Console.WriteLine(e.Message)

          buildLogStream = Nothing
      End Try

      If Not buildLogStream Is Nothing Then
               
          Console.WriteLine("Nmake output logged to {0}", _
              buildLogFile)
    
          buildLogStream.WriteLine()
          buildLogStream.WriteLine(DateTime.Now.ToString())
          
          If Not String.IsNullOrEmpty(nmakeArguments) Then
              buildLogStream.Write("Command line = NMake {0}", _
                        nmakeArguments)
          Else 
              buildLogStream.Write("Command line = Nmake")
          End If
          
          buildLogStream.WriteLine()
          buildLogStream.Flush()
            
          logMutex.ReleaseMutex()
      
           ' Start the process.
           Console.WriteLine()
           Console.WriteLine("\nStarting Nmake command...")
           Console.WriteLine()
           nmakeProcess.Start()

           ' Start the asynchronous read of the error stream.
           nmakeProcess.BeginErrorReadLine()

           ' Start the asynchronous read of the output stream.
           nmakeProcess.BeginOutputReadLine()
    
           ' Let the nmake command run, collecting the output.
           nmakeProcess.WaitForExit()

           nmakeProcess.Close()
           buildLogStream.Close()
           logMutex.Dispose()
       End If
   End Sub 
   
    Private Shared Sub NMakeOutputDataHandler(sendingProcess As Object, _
       outLine As DataReceivedEventArgs)

        ' Collect the output, displaying it to the screen and 
        ' logging it to the output file.  Cancel the read
        ' operation when the maximum line limit is reached.

        If Not String.IsNullOrEmpty(outLine.Data) Then
            logMutex.WaitOne()

            currentLogLines = currentLogLines + 1
            If currentLogLines > maxLogLines Then
                
                ' Display the line to the console.
                ' Skip writing the line to the log file.
                Console.WriteLine("StdOut: {0}", outLine.Data)
            Else If currentLogLines = maxLogLines Then
                
                LogToFile("StdOut", "<Max build log limit reached!>", _
                    true)
    
                ' Stop reading the output streams.
                Dim p As Process = sendingProcess 
                If Not (p Is Nothing) Then
                    p.CancelOutputRead()
                    p.CancelErrorRead()
                End If
            Else 
                ' Write the line to the log file.
                LogToFile("StdOut", outLine.Data, true)
            End If

            logMutex.ReleaseMutex()
        End If
 
    End Sub 
   
   Private Shared Sub NMakeErrorDataHandler(sendingProcess As Object, _
        errLine As DataReceivedEventArgs)

      ' Collect the error output, displaying it to the screen and 
      ' logging it to the output file.  Cancel the error output
      ' read operation when the maximum line limit is reached.

        If Not String.IsNullOrEmpty(errLine.Data) Then
            logMutex.WaitOne()

            currentLogLines = currentLogLines + 1
            If currentLogLines > maxLogLines Then
                
                ' Display the line to the console.
                ' Skip writing the line to the log file.
                Console.WriteLine("StdErr: {0}", errLine.Data)
            Else If currentLogLines = maxLogLines Then
                
                LogToFile("StdErr", "<Max build log limit reached!>", _
                    true)
    
                ' Stop reading the output streams.
                Dim p As Process = sendingProcess 
                If Not (p Is Nothing) Then
                    p.CancelOutputRead()
                    p.CancelErrorRead()
                End If
            Else 
                ' Write the line to the log file.
                LogToFile("StdErr", errLine.Data, true)
            End If

            logMutex.ReleaseMutex()
        End If
 
    End Sub
   
    Private Shared Sub LogToFile(logPrefix As String, _
                                logText As String, _
                                echoToConsole As String)

        ' Write the specified line to the log file stream.
        Dim logString As StringBuilder = New StringBuilder()

        If Not String.IsNullOrEmpty(logPrefix) Then
                logString.AppendFormat("{0}> ", logPrefix)
        End If

        If Not String.IsNullOrEmpty(logText) Then
            logString.Append(logText)
        End If

        If Not buildLogStream Is Nothing Then
        
            buildLogStream.WriteLine("[{0}] {1}", _
                DateTime.Now.ToString(), logString.ToString())
            buildLogStream.Flush()
         End If
            
         If echoToConsole Then
            Console.WriteLine(logString.ToString())
         End If
  
    End Sub 
End Class

Hinweise

BeginOutputReadLine startet einen asynchronen Lesevorgang für den StandardOutput Stream. CancelOutputRead beendet den asynchronen Lesevorgang.

Nach dem Abbrechen können Sie asynchrone Lesevorgänge fortsetzen, indem Sie erneut aufrufen BeginOutputReadLine .

Wenn Sie aufrufen CancelOutputRead, werden alle laufenden Lesevorgänge für StandardOutput abgeschlossen, und der Ereignishandler wird deaktiviert. Alle weiteren umgeleiteten Ausgaben an StandardOutput werden in einem Puffer gespeichert. Wenn Sie den Ereignishandler mit einem Aufruf von BeginOutputReadLineerneut aktivieren, wird die gespeicherte Ausgabe an den Ereignishandler gesendet, und die asynchronen Lesevorgänge werden fortgesetzt. Wenn Sie den Ereignishandler ändern möchten, bevor Sie asynchrone Lesevorgänge fortsetzen, müssen Sie den vorhandenen Ereignishandler entfernen, bevor Sie den neuen Ereignishandler hinzufügen:

// At this point the DataReceivedEventHandler(OutputHandler1)
// has executed a CancelOutputRead.

// Remove the prior event handler.
process.OutputDataReceived -=
    new DataReceivedEventHandler(OutputHandler1);

// Register a new event handler.
process.OutputDataReceived +=
    new DataReceivedEventHandler(OutputHandler2);

// Call the corresponding BeginOutputReadLine.
process.BeginOutputReadLine();

Hinweis

Sie können keine asynchronen und synchronen Lesevorgänge für den umgeleiteten StandardOutput Stream kombinieren. Sobald der umgeleitete Stream eines im Process asynchronen oder synchronen Modus geöffnet wird, müssen sich alle weiteren Lesevorgänge für diesen Stream im gleichen Modus befinden. Wenn Sie einen asynchronen Lesevorgang abbrechen StandardOutput und dann erneut aus dem Stream lesen müssen, müssen BeginOutputReadLine Sie verwenden, um asynchrone Lesevorgänge fortzusetzen. Folgen CancelOutputRead Sie nicht einem Aufruf der synchronen Lesemethoden StandardOutput wie Read, ReadLineoder ReadToEnd.

Gilt für:

Weitere Informationen