BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

.NET Framework
.NET 2.0+

Capturing the Standard Output of a Process

Rather than recreating some functionality, it can be easier to launch existing processes. When a program can output textual information and error details, the software launching the process can subscribe to events and capture that information.

Launching Processes

You can launch processes such as executables and batch files using the Process class, which is found in the System.Diagnostics namespace. This is handy if you are creating an application that is designed to launch other software or if you want to take advantage of command line programs, rather than recreate functionality that is provided by Microsoft Windows.

When you launch programs that send information to the standard output and standard error streams, you can redirect those streams in order to capture the messages. You might decide to display or log this information, or to interrogate it and react according to the output and errors.

In this article we'll see how to launch a process and capture its output. We'll do this by starting a batch file from a C# console application. To follow the examples, create a new batch file with the contents shown below. The file outputs two messages. The C# sample code assumes that you save this file in the "c:\Test" folder and name it "Test.bat". If you use a different path or file name you'll need to update the code accordingly.

@echo off
echo Hello!
echo Goodbye!

Process Start Information

When you wish to capture the standard output from a launched program you need to provide the process with a ProcessStartInfo object. Such an object provides the options to use when you start the external program. There are four properties that we need to set:

  • FileName. This string property specifies the path of the file to be launched.
  • UseShellExecute. When set to true, this property indicates that the process will be started by the Windows shell. When false, the executable or batch file is launched directly. In order to obtain the outputted information we must set the property to true.
  • RedirectStandardOutput. This property must be set to true if you intend to capture outputted messages.
  • RedirectStandardError. This property must be set to true in order to read the error stream.

To show the options in action create a new console application. Add the following using directive to simplify access to the Process class.

using System.Diagnostics;

We can now create the start information to launch our batch file. Add the following code to the Main method, remembering to change the path if your batch file is not named as previously described.

ProcessStartInfo startInfo = new ProcessStartInfo(@"c:\Test\Test.bat");
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;

Process Events

We can now create a Process object and set its start-up information using the StartInfo property. We also need to subscribe to two events provided by the Process class. These are OutputDataReceived, which is raised when a line of text is outputted, and ErrorDataReceived, which is raised in response to an error.

Add the following code to the end of the Main method.

Process process = new Process();
process.StartInfo = startInfo;
process.OutputDataReceived += CaptureOutput;
process.ErrorDataReceived += CaptureError;

Both of the events provide an instance of the DataReceivedEventArgs class to the event handler. This object contains a Data property, which holds the received message. The information is in the form of a string, which can be null when the process is exiting.

We'll simply output any message that we receive. Standard output will be shown in green and errors in red. Add the following event handler methods to the Program class:

static void CaptureOutput(object sender, DataReceivedEventArgs e)
{
    ShowOutput(e.Data, ConsoleColor.Green);
}

static void CaptureError(object sender, DataReceivedEventArgs e)
{
    ShowOutput(e.Data, ConsoleColor.Red);
}

static void ShowOutput(string data, ConsoleColor color)
{
    if (data != null)
    {
        ConsoleColor oldColor = Console.ForegroundColor;
        Console.ForegroundColor = color;
        Console.WriteLine("Received: {0}", data);
        Console.ForegroundColor = oldColor;
    }
}

To complete the sample program we now need to launch the process and start listening to the process's streams. Starting the process is the same as when not reading the output streams; you simply call the Start method. To capture the standard output data call BeginOutputReadLine. For the error capture, call BeginErrorReadLine.

Add the following code to the end of the Main method. The final call to WaitForExit simply waits for the launched process to close. Without this call our console application would exit before the batch file is completely executed, as it runs asynchronously.

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();

Try running the program by pressing Ctrl-F5. You should see the following results.

Received: Hello!
Received: Goodbye!
15 February 2013