tags:

views:

773

answers:

5

im starting a console application,
but when I redirect the standardoutput I always get nothing!!
when I dont redirect it, and set createnowindow to false,
I see everything correctly in the console, but when I redirect it, standardoutput.ReadToEnd() always returns an emty string.

        Process cproc = new Process();
        cproc.StartInfo.CreateNoWindow = true;
        cproc.StartInfo.FileName = Dest;
        cproc.StartInfo.RedirectStandardOutput = true;
        cproc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        cproc.StartInfo.UseShellExecute = false;
        cproc.EnableRaisingEvents = true;
        cproc.Start();
        cproc.Exited += new EventHandler(cproc_Exited);
        while(!stop)
        {
           result += cproc.StandardOutput.ReadToEnd();
        }

the eventhandler cproc_exited just sets stop to true.
can someone explain why result is always string.Empty?

+3  A: 

You have redirection of standard out disabled. Try changing

cproc.StartInfo.RedirectStandardOutput = false;

into

cproc.StartInfo.RedirectStandardOutput = true;

Does the following sample from MSDN work for you?

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
0xA3
still changes nothing
alex
well this makes the window appear-but thats empty, and my result string is empty, too.this is really confusing
alex
Have you checked standard error: `output = p.StandardError.ReadToEnd();`?
0xA3
+1  A: 

Why are you looping? Once it's read to the end, it's not going to be able to read any more data, is it?

Are you sure the text is actually being written to StandardOutput rather than StandardError?

(And yes, obviously you want to set RedirectStandardOutput to true rather than false. I assumed that was just a case of you copying the wrong version of your code.)

EDIT: As I've advised in the comments, you should read from standard output and standard error in separate threads. Do not wait until the process has exited - this can end up with a deadlock, where you're waiting for the process to exit, but the process is blocking trying to write to stderr/stdout because you haven't read from the buffer.

Alternatively you can subscribe to the OutputDataReceived and ErrorDataReceived events, to avoid using extra threads.

Jon Skeet
if I change it to while (!stop) { } s += convproc.StandardOutput.ReadToEnd();i get a deadlock
alex
heey, it works!! looks like my friend (who made the console programm) messed it up! it writes everything in the error stream!! I'll have to talk to him, maybe he can fix this. Thanks for youre quick answer! you saved me from sitting hours and hours in front of my pc and trying to search for a stupid error :)
alex
@alex: Take out that while loop - it shouldn't be there. Ideally, use separate threads - one to read from `StandardOutput` and one to read from `StandardError`.
Jon Skeet
well I now changed it from `ReadToEnd` to `ReadLine`
alex
@alex: In that case you *will* need a loop (until ReadLine returns false) - but unless you actually need the data before the process finishes, I would strongly encourage you to use ReadToEnd from two threads (one for stdout, one for stderr).
Jon Skeet
but stdout is always empty! why should I read that?
alex
@alex: It's empty right now, but do you really want to end up with a deadlock if that changes in the future?
Jon Skeet
I had about 20 deadlocks today, I do not need any more of them. Well youre right, I'll loose nothing if I just read from stdout. That'll save me time in future
alex
A: 

You would have to use cproc.WaitForExit(); before reading the standardoutput. This should solve your problem & you could avoid your loop as well.

Ravia
that ends in a deadlock, too
alex
I don't think deadlock means what you think it means. WaitForExit doesn't return until the process has exited, and that's the whole point of it.
CannibalSmith
Actually this *is* a deadlock situation, potentially: the child process blocking as it tries to write to stdout, and the parent process blocking until it's finished...
Jon Skeet
that is exacly what I was trying to aviod, because I read about it in MSDN
alex
A: 

Get rid of the loop and move the call to ReadToEnd to cproc_Exited.

CannibalSmith
Bad idea: the process will hang if it tries to write a lot of data which nothing is reading.
Jon Skeet