RE: Strange behavior of redirected stdout. Streams Broken?



Things have progressed. There is still one problem.

At present, I can capture stderr and stdout from a console app. But some
console
apps behave differently than others. The Intel/C app I want to capture
appeared
to be buffering so that I could not retrieve the output until after it
completed (or,
possibly, when the buffer filled). Other apps I could capture line for line
as they
wrote to stdout. I created a .NET console app and its output could be captured
line-by-line by my capture software.

I was about to write it off as something odd about Intel's C compiler, but I
gave
it one more try. I wrote a super simple console program in VC++ 6:

#include <stdio.h>
#include <windows.h>

int main(int argc, char* argv[])
{
int n;
for(n=1; n < 20; n++)
{
printf("This is a test of just one line. Line %d\n", n);
Sleep(500);
};
return 0;
}

I expected to capture this line by line, but to my surprise it behaved
exactly as
the Intel/C app. It was almost certainly some type of buffering, so I added:

fflush(stdout);
right after the printf.

This fixed it -- I could capture line-by-line.

Now here's the problem: how is it that when these programs are executed
in a cmd.exe window, their output is displayed line by line? In .NET, when
I start these, it is with System.Diagnostics.Process.

The startinfo:
oProc.StartInfo.UseShellExecute = False ' can't use shell
execute when we will be redirecting output.
oProc.StartInfo.ErrorDialog = False
oProc.StartInfo.CreateNoWindow = True
oProc.StartInfo.RedirectStandardError = True
oProc.StartInfo.RedirectStandardInput = bUseCmdExe
oProc.StartInfo.RedirectStandardOutput = True

Pretty straight forward. Later, when reading:

Dim sr As StreamReader = oProc.StandardOutput
Dim sLine As String

sLine = sr.ReadLine
While Not (sLine Is Nothing)
RaiseEvent OutputText(sLine)
sLine = sr.ReadLine
End While

I've tried using peek to check if there are any characters before the
line completes, but it consistently blocks and doesn't say there's
anything until the process terminates (unless I use the fflush).

I've gone to the base stream and fooled with that, but found
nothing that would get the characters I needed. I'm beginning
to think I need to use the stream handle and Win32 APIs to
figure out something, which would be a drag.

So... how do I read the stream so that the data which is being
written to it appears at the other end? Remember, cmd.exe
IS doing just that, so it doesn't depend on me changing the application
in any way -- it must be something about the process itself.

One thought: perhaps when running under cmd.exe, the process
started is a child of cmd.exe, so cmd.exe can give it stdout directly,
and thus control the buffering of the pipe.

Is there some way in .NET for me to do something similar, or
to get better control of the stdout pipe?

Thanks!
.



Relevant Pages

  • Re: Sound recording - HELP!
    ... maybe this would be a great app to get my ... listing on the radio. ... Private Sub StartRecording() ... mciSimpleSendString("open new type waveaudio alias capture") ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Captureing device error: "Busy
    ... Can you show me how to locate the app in MCE? ... >>> I have the same error message when I tired to capture analog video ... >>> the video and sound from my VCR. ...
    (microsoft.public.windowsxp.video)
  • Re: Windows media encoder
    ... Each running app will place an Icon here ... maybe causing a conflict with your capture software: ... Did you open Windows Task Manager? ... Running Processes and CPU Usage. ...
    (microsoft.public.windowsxp.video)
  • splitting stderr/stdout without using file
    ... I need to capture stdout and stderr but without using files for the ... This script will be part of a logging function that is called ...
    (comp.lang.perl.misc)
  • SetCapture, mouse and key events
    ... turns on drawing, and the second mouse click turns it off. ... Capture property would make sure the window gets all mouse messages until ... I'm just experimenting with this app; ...
    (microsoft.public.dotnet.framework.windowsforms)