A couple months ago there was a discussion here (started by Paul Randall)
regarding using WshShell.Exec and trying to grab the output via
WshScriptExec.StdOut. The problem was never fully resolved, but I think
have the answer.
The problem is that the program being Exec'd is buffering its output. I had
the same problem, but luckily the program I was trying to run was a C++
program that I had written, so I was able to go in and turn off buffering
for stdout. As soon as I did that, I was able to grab the output as it was
generated.
Of course, if you don't have the source to the program you're running (as I
believe was the case with Paul's post in January), you're pretty much SOL,
but at least now you know why you're SOL (:-).
BTW, the reason the Microsoft sample code works (that is, the code in the
description of WshScriptExec.StdOut) is that anytime a program sees an input
request for stdin, it flushes stdout. (At least, the C run-time lib does
this; I assume other languages would also.) The sample program grabs
characters from StdOut until it gets the prompt it expected, at which point
it knew the program was waiting for input. But the fact that the program
was now waiting for input is the only reason the text was written to StdOut!
So if the program you're Exec'ing doesn't read stdin, you'll only get the
output when the output buffer is full (probably every 512 characters, or
some other reasonable power of 2), or when the program ends.
It would be nice if Microsoft's C run-time would detect when stdout is a
pipe (which I'm sure is what WshScriptExec.StdOut really is), and would turn
off buffering in that case, the same as it does when it knows it's writing
to a console.
- Rich Wells


