views:

1001

answers:

2

I'm spawning a child process that runs in a visible console window (it's a batch file that runs MSBuild), and I'd like to have the output generated by the process displayed in the visible console window, as well as capture that output so I can process it in code. I've read several other questions and the MSDN documentation dealing with ProcessStartInfo.RedirectStandardOutput and the like, and I can capture the output from the redirected stream and process it in code just fine:

Process msBuild = new Process();
msBuild.StartInfo.FileName = "Build.bat";
msBuild.StartInfo.UseShellExecute = false;
msBuild.StartInfo.RedirectStandardOutput = true;
msBuild.Start();
string output = msBuild.StandardOutput.ReadToEnd();
msBuild.WaitForExit();

The problem is that the output is not displayed in the console window of the child process; I just get a blank console window on the screen while the process is running, which disappears when it's finished.

I suppose I could hide the actual child process window, and display a second window that I would simply write the output to as it was captured, but that seems like more work than is necessary. Is there a way to have the output displayed in the console window and still capture it for processing when it's done?

+2  A: 

Once you've redirected standard out it's no longer directed at the console. To write to the console you'll have to do it manually.

If you want to display output as the process executes, instead of in 1 big dump at the end, you can use the "OutputDataReceived" event of the Process class.

Arnshea
Wow - I hadn't seen OutputDataReceived before. Neat!
Jon Skeet
That seems to answer the question of whether or not I can have the output displayed in the console window owned by the child process and redirected to the parent process at the same time.My next question would be, is it possible to not redirect the output, and just capture it all from the console when the process exits?Or, if not, what's the best way to create a console window manually so that I can write the redirected output to it as the process executes (using `OutputDataReceived`)?
mjl5007
Have a look at http://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived.aspx . It has an example (you may want turn off all languages but C#)
Arnshea
+2  A: 

Here is what I've used, without using a separate thread:


using(System.Diagnostics.Process proc = new System.Diagnostics.Process())
{
   proc.EnableRaisingEvents = false;
   proc.StartInfo.RedirectStandardOutput = true;
   proc.StartInfo.CreateNoWindow = true;
   proc.StartInfo.UseShellExecute = false;
   proc.StartInfo.Verb = "open";
   proc.StartInfo.FileName = "XXXX";
   proc.Start();
   String sLine = "";
   while ((sLine = proc.StandardOutput.ReadLine()) != null)
   {
      System.Console.WriteLine(sLine);
   }
   proc.WaitForExit(); //Jon Skeet was here!
   errorCode = proc.ExitCode;
   proc.Close();
}
crashmstr
I was assuming that the OP wanted the spawning process to keep running - I hadn't noticed the call to WaitForExit. I would use WaitForExit rather than your while loop though - tight loops aren't a good idea.
Jon Skeet
I'm trying to remember if there was a reason I did not use WaitForExit there.
crashmstr
Looking at my SVN history, it was because I used to have it as "while(!proc.HasExited) { /*read stuff in here*/ }", but that did not get all of the text, and when I moved it outside of the reading loop, did not think to change it to a WaitForExit.
crashmstr