title: Problem with System.Diagnostics.Process RedirectStandardOutput to appear in Winforms Textbox in real-time
body: <p>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.</p>
  
  <p>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.  </p>
  
  <p>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.</p>
  
  <p>Grateful for any advice on this.</p>
  
  <p>Here's an extract of the code</p>
  
  <pre><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();
      }
  }
  </code></pre>