views:

1677

answers:

2

I have a GUI application within which i'm spawning a console application using Process class.

Process p1 = new Process();
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = "/pn abc.exe /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = true;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);
p1.ErrorDataReceived += new DataReceivedEventHandler(errorreceived);
p1.Start();
tocmd = p1.StandardInput;
p1.BeginOutputReadLine();
p1.BeginErrorReadLine();

Now i have a problem that, though it reads the console output asynchronously but it seems to fire the event only when the internal buffer is filled with some amount. I want it to display data as it comes. If there's 10 bytes in buffer, let it display the 10 bytes. My program implements sleep() call internally, so i need to print the data till it goes to sleep.

How can i do it?

=============

As it was mentioned the output is line buffered, i tried the following change in the code

p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = pnswitch + " /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = false;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.Start();
tocmd = p1.StandardInput;
MethodInvoker mi = new MethodInvoker(readout);
mi.BeginInvoke(null, p1);

and inside readout i wrote

void readout()
    {
        string str;
        while ((str = p1.StandardOutput.ReadLine()) != null)
        {
            richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput), new object[] { str });
            p1.StandardOutput.BaseStream.Flush();
        }
    }

So i think it now monitors when each line is written and it prints it right? this too didn't work. Any thing wrong there?

+2  A: 

The Output and Error Data received is line buffered, and will only fire when a newline is added.

Your best bet is to use you own reader that can read the input, byte by byte. Obvioulsly, this would have to be non-blocking :)

leppie
any idea as how can i go about making my own reader? Can't i write some function which monitors the stdoutput stream and reads from it everytime it has some data?
Anirudh Goel
Yes, thats the idea. You read the StandardOutput from another thread.
leppie
i've changed the code, and made it read line wise. can you have a look?
Anirudh Goel
Dont use ReadLine! Use Read() instead, and cast to char, then append to string or write somewhere else.
leppie
+1  A: 

In order to achieve this, you must use synchronous read operations on a redirected stream. Your code would look like this (MSDN Sample):

// 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();

In order to achieve async behavior you would have to use some threads.

MSDN Article here

Bogdan Maxim
I made a async call to it. Can you have a look at the updated question and comment on it?
Anirudh Goel