Wednesday, July 26, 2006
C# - Redirecting output and input from a Process
So one of things I'm currently working on is running a separate, command line process from within my main C# program, interacting with it completely. There are loads of potential uses to this, but I'm using it effectively for reading and writing to a Linux CLI running on Cygwin, which means I can control a Linux program from a Windows Form.
It uses System.Diagnostics.Process, which is quite well represented in the MSDN library.
The key things to use, for a Process called myProcess are:
// first two hide myProcess' window
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = true;
//Redirect input and output to parent program
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardInput = true;
Inputting data to the process is easy - to write to the input stream we just use myProcess.StandardInput.WriteLine() after calling myProcess.Start() - but grabbing the output is not so simple. If we wait for myProcess to terminate before we carry on running our main program, we can use myProcess.StandardOutput.ReadToEnd()or similar. However, if we want to continuously read from the Output stream, we need to create a new thread for it, and that means using: mProcess.BeginOutputReadLine() instead - and to use this, we need to have defined:
myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived);
where myProcess_OutputDataReceived contains some code (such as Console.WriteLine(e.Data); that deals with the output data.
Writing to the console is thread safe, but writing to a Windows Form control (e.g. a RichTextBox) is not thread safe. The work-around for that is a little tricky but fortunately it's covered in detail here.
It uses System.Diagnostics.Process, which is quite well represented in the MSDN library.
The key things to use, for a Process called myProcess are:
// first two hide myProcess' window
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = true;
//Redirect input and output to parent program
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardInput = true;
Inputting data to the process is easy - to write to the input stream we just use myProcess.StandardInput.WriteLine() after calling myProcess.Start() - but grabbing the output is not so simple. If we wait for myProcess to terminate before we carry on running our main program, we can use myProcess.StandardOutput.ReadToEnd()or similar. However, if we want to continuously read from the Output stream, we need to create a new thread for it, and that means using: mProcess.BeginOutputReadLine() instead - and to use this, we need to have defined:
myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived);
where myProcess_OutputDataReceived contains some code (such as Console.WriteLine(e.Data); that deals with the output data.
Writing to the console is thread safe, but writing to a Windows Form control (e.g. a RichTextBox) is not thread safe. The work-around for that is a little tricky but fortunately it's covered in detail here.