There's even a Microsoft Connect entry that has been filed since September 2005! And a several blog/forum posts [1: Jay R. Wren] [2: MSDN] [3: StackOverflow] about it. What has Microsoft done about it? Nothing! Is it surprising? Not at all - none of the bugs I've blogged about has been fixed so far, critical or not. All they did was whinge about how hard/expensive it is to fix.
So here it is Microsoft, I've come up with a solution for you (feel free to rip me off).
Essentially, what Microsoft needs to do is change
Process.StartWithCreateProcess
such that standardOutput
and standardError
are both assigned a specialised type of StreamReader
(e.g. PipeStreamReader
).In this
PipeStreamReader
, they need to override both ReadBuffer
overloads (i.e. need to change both overloads to virtual in StreamReader
first) such that prior to a read, PeekNamedPipe
is called to do the actual peek. As it is at the moment, FileStream.Read()
(called by Peek()
) will block on pipe reads when no data is available for read. While a FileStream.Read()
with 0 bytes works well on files, it doesn't work all that well on pipes! In fact, the .NET team missed an important part of the pipe documentation - PeekNamedPipe WinAPI.The PeekNamedPipe function is similar to the ReadFile function with the following exceptions:
...
The function always returns immediately in a single-threaded application, even if there is no data in the pipe. The wait mode of a named pipe handle (blocking or nonblocking) has no effect on the function.
There you go. It looks like Microsoft forgot about the PeekNamedPipe WinAPI that the other Microsoft team wrote. Wow! That's embarrassing!