views:

257

answers:

3

Hi,

I'm spawning a process from Win32 using CreateProcess, setting the hStdOutput and hStdError properties of STARTUPINFO to pipe handles created with CreatePipe. I've got two threads reading the pipes, waiting for data to become available (or the process to complete, at which point it checks that there is no data left before terminating the thread).
As data becomes available, I write the output out to effectively a big textbox.

What's happening is the output is being buffered, so a slow running process just gets chunks of data thrown at the text box, but not "as it happens".

I'm not sure if it's the pipe that's doing the buffering, or something to do with the redirection.

Is there any way to either set the pipe to be unbuffered, or start the process in such a way that the stdout is sent as soon as possible?

I'm testing with a test app that prints lines one second apart

Here is line one
(waits one second)
Here is line two
(waits one second)
... etc

Thanks ever so much for any pointers you can give me!

Cheers,

Dave.

A: 

There's SetNamedPipeHandleState, but it only controls buffering for remote pipes, not when both ends are on the same computer.

Ben Voigt
Yes, I've seen that, but, as you say, it doesn't change anything when both ends are on the same computer
Dave Brotherstone
+1  A: 

The buffering is probably in the C runtime (printf etc) and there is not much you can do about it (IIRC it does a isatty() check to determine a buffering strategy)

Anders
That would be the answer in POSIX. But Windows has no concept of a tty, nor any `isatty` function.
Ben Voigt
@Ben Voigt: the MS c runtime still has it: http://msdn.microsoft.com/en-us/library/f4s0ddew%28v=VS.80%29.aspx
w0lo
shaking head in amazement at the ".NET Framework Equivalent" list, none of which are equivalent in any way
Ben Voigt
BTW here's the closest Win32 API equivalent to `isatty`: http://msdn.microsoft.com/en-us/library/aa364960.aspx
Ben Voigt
I've ticked this answer, as it looks like the existing code works with other things that show output slowly - eg compilers. I had assumed that the output side was all the same.
Dave Brotherstone
A: 

It seems to me you can solve the problem if you set the hStdOutput and hStdError of STARTUPINFO not to pipe handles created with CreatePipe, but instead of that you create a named pipes (with CallNamedPipe function exactly like you used if before also using SECURITY_ATTRIBUTES with bInheritHandle = TRUE, see http://msdn.microsoft.com/en-us/library/aa365782.aspx) and then open there by name with respect of CreateFile using FILE_FLAG_WRITE_THROUGH flag. Like you can read on the MSDN (http://msdn.microsoft.com/en-us/library/aa365592.aspx):

The pipe client can use CreateFile to enable overlapped mode by specifying FILE_FLAG_OVERLAPPED or to enable write-through mode by specifying FILE_FLAG_WRITE_THROUGH.

So just reopen the pipe with respect of CreateFile using FILE_FLAG_WRITE_THROUGH flag and set the handle/handles to hStdOutput and hStdError of STARTUPINFO.

Oleg
FILE_FLAG_WRITE_THROUGH0x80000000Write-through mode is enabled. This mode affects only write operations on byte-type pipes and, then, **only when the client and server processes are on different computers.** If this mode is enabled, functions writing to a named pipe do not return until the data written is transmitted across the network and is in the pipe's buffer on the remote computer. If this mode is not enabled, the system enhances the efficiency of network operations by buffering data until a minimum number of bytes accumulate or until a maximum time elapses.
Ben Voigt