21

I am going to execute a Process (lame.exe) to encode a WAV file to MP3.

I want to process the STDOUT and STDERR of the process to display progress information.

Do I need to use threading? I can't get my head around it.

Some simple example code would be appreciated.

Thanks

dave
  • 273
  • 2
  • 5
  • I found the sample [here](http://msdn.microsoft.com/en-us/library/system.diagnostics.process%28v=vs.80%29.aspx) that shows how to read both stdout and stderr with threads helpful. See also http://cleancode.sourceforge.net/api/csharp/html/T_CleanCode_IO_ExecProcess.htm. – Bill Hoag Mar 08 '12 at 18:44

3 Answers3

7

If running via the Process class, you can redirect the streams so you may process them. You can read from stdout or stderr synchronously or asynchronously. To enable redirecting, set the appropriate redirection properties to true for the streams you want to redirect (e.g., RedirectStandardOutput) and set UseShellExecute to false. Then you can just start the process and read from the streams. You can also feed input redirecting stdin.

e.g., Process and print whatever the process writes to stdout synchronously

var proc = new Process()
{
    StartInfo = new ProcessStartInfo(@"SomeProcess.exe")
    {
        RedirectStandardOutput = true,
        UseShellExecute = false,
    }
};
if (!proc.Start())
{
    // handle error
}
var stdout = proc.StandardOutput;
string line;
while ((line = stdout.ReadLine()) != null)
{
    // process and print
    Process(line);
    Console.WriteLine(line);
}
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
6

You should be able to listen to the STDOUT with the Process.OutputDataReceived event. There is an example on the MSDN page. There is also an Process.ErrorDataReceived event for STDERR.

Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108
6

There is an MSDN example for this... Here is a simplified version:

var StdOut = "";
var StdErr = "";

var stdout = new StringBuilder();
var stderr = new StringBuilder();

var psi = new ProcessStartInfo();
psi.FileName = @"something.exe";
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;

var proc = new Process();
proc.StartInfo = psi;
proc.OutputDataReceived += (sender, e) => { stdout.AppendLine(e.Data); };
proc.ErrorDataReceived += (sender, e) => { stderr.AppendLine(e.Data); };
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit(10000); // per sachin-joseph's comment

StdOut = stdout.ToString();
StdErr = stderr.ToString();
  • Always call `waitForExit` with a timeout to prevent the chance of an infinite wait. `waitForExit(10000)` => waits for 10 seconds. – Sachin Joseph Sep 04 '17 at 08:46