Question

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?

Was it helpful?

Solution

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 :)

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top