1

From a C# form I am running a process with start info similar to Redirect console output to textbox in separate program and C# get process output while running, the process runs correctly however the output takes a long time to appear in the DataReceived event.

I would like to see the text as soon as the process generates it; according to Process standard output cannot be captured? (first comment) I need to wait until a buffer of 2 to 4 kb to fill before the event is fired.

As requested this is the code:

void pcs_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (!string.IsNullOrEmpty(e.Data)) 
        textBox1.BeginInvoke((Action)delegate { textBox1.AppendText(text + "\n"); });
}

private void LER_Go_Click(object sender, EventArgs e)
{
    // variables LiDARExtRep contains the full path to an executable file
    // that runs in DOS and produces verbose output.
    // LER_Path.Text is the parameter passed to LiDARExtRep (only one arg for this example)
    ProcessStartInfo pStartInfo = new ProcessStartInfo(LiDARExtRep, LER_Path.Text);    
    pStartInfo.UseShellExecute = false;
    pStartInfo.ErrorDialog = false;
    pStartInfo.RedirectStandardError = true;
    pStartInfo.RedirectStandardInput = true;
    pStartInfo.RedirectStandardOutput = true;
    pStartInfo.CreateNoWindow = true;

    System.Diagnostics.Process pcs = new System.Diagnostics.Process();
    pcs.StartInfo = pStartInfo;

    bool pStarted = pcs.Start();

    pcs.OutputDataReceived += new DataReceivedEventHandler(pcs_OutputDataReceived);

    pcs.BeginOutputReadLine();
    pcs.WaitForExit();
}

I don't see anything special about it, it's exactly the same as the examples I referenced... a simple "Dir","/b/s" in the constructor should produce the same results.

Is there a way to diminish the buffer to a few bytes or a better way to execute a command line tool and receive the output 'real time'?

Background: I wrote a number of command line programs in C++, which work great, but the younger generation seem scared of DOS, so I am creating a form (GUI) to collect the parameters for these tools as it seems a lot less work than trying to put a GUI on each program in C++. If I can't get real time responses I will have to UseShellExecute = true; and show the command window.

8
  • Perhaps you can run your process inside a BackGroundWorker msdn.microsoft.com/en-us/library/… Commented Jul 1, 2015 at 5:28
  • How would that help @jmc? Is there a feedback on the BackgroundWorker that will take stdout from the executable? All I see there is a percentage. Commented Jul 1, 2015 at 5:30
  • Can you post your reproducible code for running the process? Then someone could find a clue. Commented Jul 1, 2015 at 15:33
  • @emoacht, I have included the code. It is (almost) a direct copy of the help code at MSN/Stack Overflow (thank you to the respective authors). Commented Jul 1, 2015 at 21:21
  • 1
    setvbuf(stdout,NULL,_IONBF,0); before first printf command should help. Commented Jul 2, 2015 at 1:43

1 Answer 1

5

The buffering happens on console program end. By default, stdout is fully buffered if known to be redirected:

If stdout is known to not refer to an interactive device, the stream is fully buffered. Otherwise, it is library-dependent whether the stream is line buffered or not buffered by default (see setvbuf). Source

So, unless you can alter the console program source to disable buffering, nothing can be done on GUI program side.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much, it's working like a charm now... every line is appearing in the listbox quickly. One thing though, I had to change the process.WaitForExit(); to do { application.DoEvents();} while (!process.HasExited); to get the form to respond properly.
@MichaelMiles-Stimson IMO, it is better do attach handler to process.Exited instead of process.WaitForExit() or while (!process.HasExited).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.