A customer wanted to know how their C# program could read its own standard output. They tried this:
// Get my process Process p = Process.GetCurrentProcess();
// Make sure my standard output is not redirected p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = false;
// Now read it – fails string output = p.StandardOutput.ReadToEnd();
They got an exception saying, “StandardOut has not been redirected or the process hasn’t started yet.”
The StandardOutput property is valid only after you call Process.Start. Specifically, if you call Process.Start when RedirectStandardOutput is set to true the CLR creates a pipe and connects the write end of the pipe to the child’s standard output and the read end of the pipe to the Process.StandardOutput property. If you never call Process.Start, or you did not enable standard output redirection, then the Process.StandardOutput property will not be set and will not work.
In my opinion, putting properties on the Process object that are meaningful only for started processes was a mistake. Those properties should have been put on a new class like ProcessStartResult. That way, it’s clear that the only way to get them is to start a process.
If you are a C# process, you could call Console.SetOut() to replace the standard output with a pipe you created.¹ However, if anybody read the Console.Out property and saved it in a variable, then they would still be operating on the original standard output stream and not your replacement.
The most reliable solution is to relaunch yourself as a child process with redirected standard output and have the parent read from the resulting Process.StandardOutput stream while the child writes to it.
¹ This is the CLR analog to the Win32 function SetStdHandle(). Note that Win32 and the CLR have separate bookkeeping for this. The CLR initializes its standard output from the Win32 standard output, but the two can diverge afterward because the CLR does not bother to keep its value in sync with Win32 or vice versa.
Note also that the analogy continues, because the analogous solution for Win32 console programs is to call SetStdHandle, but you have the same risk that somebody has already read the original standard handle and saved it away. And as we saw last time, that risk is a reality because the C runtime library does exactly that. The analogous functions to Console.SetOut() for C are those in the freopen family.
The post How can my process read its own standard output? appeared first on The Old New Thing.
From The Old New Thing via this RSS feed


