title: Unable to get Perl redirection working in C# with background worker
body: <p>I've been trying to get a Perl script to give up its output to a List box in C# without any luck.</p>
  
  <p>I've been looking on this site and others and tried multiple combinations but are still not having any joy with it, perhaps something to do with trying to do it via the background worker?</p>
  
  <p>My code below, help would be appreciated.</p>
  
  <pre><code>public partial class Form1 : Form
  {
      /// &lt;summary&gt;
      /// The backgroundworker object on which the time consuming operation shall be executed
      /// &lt;/summary&gt;
      BackgroundWorker backgroundWorker1;
      private String _dirPath = null;
  
      public Form1()
      {
          InitializeComponent();
      }
  
      // On completed do the appropriate task
      void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
          btnOpenFolder.Enabled = true;
          btnCancel.Enabled = false;
      }
  
      void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
      {
          //Here you play with the main UI thread, update a progress bar or status label
      }
  
      void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
      {
          Process p = new Process();
          p.StartInfo = new ProcessStartInfo(@"c:\Perl\bin\perl.exe");
          p.StartInfo.WorkingDirectory = @"C:\Temp\";
          p.StartInfo.FileName = @"C:\Temp\dirdupes.pl";
          p.StartInfo.Arguments = _dirPath;
          p.StartInfo.CreateNoWindow = true;
          p.StartInfo.RedirectStandardOutput = true;
          p.StartInfo.RedirectStandardInput = true;
          p.StartInfo.RedirectStandardError = true;
          p.StartInfo.UseShellExecute = false;
          p.Start();
          p.BeginErrorReadLine();
  
          //For testing
          //p.StartInfo.FileName = "cmd.exe";
          //p.StartInfo.Arguments = "dir/s";      
  
          //For testing
          //StreamReader sr = p.StandardError;
          //string line;
          //line = sr.ReadToEnd();
          //listBox1.Text = line;
  
          using (StreamReader std_out = p.StandardOutput, std_err = p.StandardError)
          {
              do
              {
                  listBox1.Items.Add(std_out.ReadToEnd()); 
                  listBox1.Items.Add(std_err.ReadToEnd());
              } while (!std_out.EndOfStream) ;
          }
  
          p.WaitForExit();
  
          if (backgroundWorker1.CancellationPending)
          {
              e.Cancel = true;
              //backgroundWorker1.ReportProgress(0);
              return;
          }
          //Report 100% completion on operation completed
          //backgroundWorker1.ReportProgress(100);
      }
  
      private void btnOpenFolder_Click(object sender, EventArgs e)
      {
          //Open folder browser for user to select the folder to scan
          DialogResult result = folderBrowserDialog1.ShowDialog();
          if (result == DialogResult.OK)
          {
              //Store selected folder path
              _dirPath = folderBrowserDialog1.SelectedPath;
          }
          else
          {
              return;
          }
  
          btnOpenFolder.Enabled = false;
          btnCancel.Enabled = true;
  
          //Start the async operation here
          backgroundWorker1.RunWorkerAsync();
      }
  
      private void btnCancel_Click(object sender, EventArgs e)
      {
          if (backgroundWorker1.IsBusy)
          {
              //Stop/Cancel the async operation here
              backgroundWorker1.CancelAsync();
          }
      }
  }
  </code></pre>
  
  <p>I ended up using this code which managed to display the Perl scripts output to my listbox</p>
  
  <pre><code>void p_DataReceived(object sender, DataReceivedEventArgs e)
      {
          if (e.Data != null &amp;&amp; e.Data.Length &gt; 0) this.Invoke(new Action(() =&gt; listBox1.Items.Add(e.Data)));
          this.Invoke(new Action(() =&gt; listBox1.TopIndex = listBox1.Items.Count - 1));
      }
  
      void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
      {
          Process p = new Process();
          var args = new ProcessStartInfo("cmd.exe");
          args.WorkingDirectory = @"C:\";
          //p.StartInfo.FileName = "perl.exe";
          args.Arguments = @"/C perl.exe C:\Temp\dirdupes.pl " + _dirPath;
          args.CreateNoWindow = true;
          args.RedirectStandardOutput = true;
          args.RedirectStandardInput = true;
          args.RedirectStandardError = true;
          args.UseShellExecute = false;
          p = Process.Start(args);
  
          p.OutputDataReceived += p_DataReceived;
          p.ErrorDataReceived += p_DataReceived;
          p.BeginErrorReadLine();
          p.BeginOutputReadLine();
  }
  </code></pre>