Problem with System.Diagnostics.Process RedirectStandardOutput to appear in Winforms Textbox in real

Posted by Jonathan Websdale on Stack Overflow See other posts from Stack Overflow or by Jonathan Websdale
Published on 2010-05-07T12:14:26Z Indexed on 2010/05/07 12:18 UTC
Read the original article Hit count: 531

Filed under:
|
|
|
|

I'm having problems with the redirected output from a console application being presented in a Winforms textbox in real-time. The messages are being produced line by line however as soon as interaction with the Form is called for, nothing appears to be displayed.

Following the many examples on both Stackoverflow and other forums, I can't seem to get the redirected output from the process to display in the textbox on the form until the process completes.

By adding debug lines to the 'stringWriter_StringWritten' method and writing the redirected messages to the debug window I can see the messages arriving during the running of the process but these messages will not appear on the form's textbox until the process completes.

Grateful for any advice on this.

Here's an extract of the code

public partial class RunExternalProcess : Form
{
    private static int numberOutputLines = 0;
    private static MyStringWriter stringWriter;

    public RunExternalProcess()
    {
        InitializeComponent();

        // Create the output message writter
        RunExternalProcess.stringWriter = new MyStringWriter();
        stringWriter.StringWritten += new EventHandler(stringWriter_StringWritten);

        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();

        startInfo.FileName = "myCommandLineApp.exe";

        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardOutput = true;
        startInfo.CreateNoWindow = true;
        startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

        using (var pProcess = new System.Diagnostics.Process())
        {
            pProcess.StartInfo = startInfo;
            pProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(RunExternalProcess.Process_OutputDataReceived);
            pProcess.EnableRaisingEvents = true;

            try
            {
                pProcess.Start();

                pProcess.BeginOutputReadLine();
                pProcess.BeginErrorReadLine();

                pProcess.WaitForExit();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                pProcess.OutputDataReceived -= new System.Diagnostics.DataReceivedEventHandler(RunExternalProcess.Process_OutputDataReceived);
            }
        }
    }

    private static void Process_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
    {
        if (!string.IsNullOrEmpty(e.Data))
        {
            RunExternalProcess.OutputMessage(e.Data);
        }
    }

    private static void OutputMessage(string message)
    {
        RunExternalProcess.stringWriter.WriteLine("[" + RunExternalProcess.numberOutputLines++.ToString() + "] - " + message);
    }

    private void stringWriter_StringWritten(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(((MyStringWriter)sender).GetStringBuilder().ToString());

        SetProgressTextBox(((MyStringWriter)sender).GetStringBuilder().ToString());
    }

    private delegate void SetProgressTextBoxCallback(string text);

    private void SetProgressTextBox(string text)
    {
        if (this.ProgressTextBox.InvokeRequired)
        {
            SetProgressTextBoxCallback callback = new SetProgressTextBoxCallback(SetProgressTextBox);
            this.BeginInvoke(callback, new object[] { text });
        }
        else
        {
            this.ProgressTextBox.Text = text;
            this.ProgressTextBox.Select(this.ProgressTextBox.Text.Length, 0);
            this.ProgressTextBox.ScrollToCaret();
        }
    }
}

public class MyStringWriter : System.IO.StringWriter
{
    // Define the event.
    public event EventHandler StringWritten;

    public MyStringWriter()
        : base()
    {
    }

    public MyStringWriter(StringBuilder sb)
        : base(sb)
    {
    }

    public MyStringWriter(StringBuilder sb, IFormatProvider formatProvider)
        : base(sb, formatProvider)
    {
    }

    public MyStringWriter(IFormatProvider formatProvider)
        : base(formatProvider)
    {
    }

    protected virtual void OnStringWritten()
    {
        if (StringWritten != null)
        {
            StringWritten(this, EventArgs.Empty);
        }
    }

    public override void Write(char value)
    {
        base.Write(value);
        this.OnStringWritten();
    }

    public override void Write(char[] buffer, int index, int count)
    {
        base.Write(buffer, index, count);
        this.OnStringWritten();
    }

    public override void Write(string value)
    {
        base.Write(value);
        this.OnStringWritten();
    }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about process