1

I have an app that runs a background process and I need to show that app's standard out during execution, like real time. I tried process.OutputDataReceived but it triggered after background process terminated itself. But I need to show standard output when that out is created by the process.

FYI: I redirected standard output and set UseShellExecute false

Here is full changes I did to the process:

ProcessStartInfo t = new ProcessStartInfo();
t.CreateNoWindow = true;
t.FileName = name;
t.Arguments = args;
t.UseShellExecute = false;
t.CreateNoWindow = true;
t.RedirectStandardOutput = true;
t.RedirectStandardError = true;

Process p = new Process();
p.StartInfo = t;
p.OutputDataReceived += P_OutputDataReceived;
p.Start();
p.BeginOutputReadLine();

And my event:

private void P_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Textbox1.Text = e.Data;
    }

Also I tried this with a python file, an executable version of it, and a C files executable, but same result at all of them.

Edit: I tried this solution but got the same result again

**Update 04.06.2018: **I just found that the P_OutputDataReceived event is also triggeredn when app waits for standart input, but still cannot found a way to trigger that event in real-time

  • Think you're missing the `BeginOutputReadLine()` call. https://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived(v=vs.110).aspx – TyCobb May 25 '18 at 18:43
  • Sorry i forgat to write it here but i wrote it in my code – M. Burak DÖNMEZ May 25 '18 at 18:47
  • Are you sure your process writes to the standard out? Test the code you have against a .bat file with a bunch of `ECHO` commands to see if your code works. – TyCobb May 25 '18 at 18:48
  • Yes i tried it with messagebox and it shows output char by char after termination – M. Burak DÖNMEZ May 25 '18 at 18:53
  • Unless you're getting blocked by synchronous code or your event is failing due to trying to set the textbox text on a different thread, what you have should work according to everything you've said. – TyCobb May 25 '18 at 18:59
  • Seems like the textbox will get overwritten with each event, and it's possible that the final event received contains an empty string or just an EOL marker. Maybe try `Textbox1.Text += e.Data;` (using `+=` instead of `=`) to append. – John Wu May 25 '18 at 19:12
  • I also think so but it even showed messagebox instead text box after termination, but i need that out, during execuiton – M. Burak DÖNMEZ May 25 '18 at 19:13

2 Answers2

0

As the executed process is also a different thread, you need to return to the UI thread for displaying data from that process. This can be achieved with the Invoke method as shown below:

private delegate void ShowDataDelegate(string data);

private void P_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
   ShowDataDelegate showDataDelegate = new ShowDataDelegate(ShowData);
   Invoke(showDataDelegate, e.Data);
}

private void ShowData(string data)
{
   textBox1.Text = data;
}
Markus
  • 63
  • 2
  • 7
0

My first answer was wrong and useless. Sorry about that. This is a Windows Forms example for how to invoke the application (Robocopy.exe) with a button press and redirect the output to a TextBox on the main form in real time.

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace testApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            using (Process tProc = new Process())
            {
                ProcessStartInfo t = new ProcessStartInfo();
                t.CreateNoWindow = true;
                t.FileName = Environment.SystemDirectory + "\\robocopy.exe";
                t.Arguments = "/?";
                t.UseShellExecute = false;
                t.CreateNoWindow = true;
                t.RedirectStandardOutput = true;
                t.RedirectStandardError = true;

                Process p = new Process();
                p.StartInfo = t;
                p.OutputDataReceived += new DataReceivedEventHandler(P_OutputDataReceived);
                p.Start();
                p.BeginOutputReadLine();                  
            }
        }

        private void P_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            try
            {
                Trace.WriteLine(e.Data);
                this.BeginInvoke(new MethodInvoker(() =>
                {
                    textBox1.AppendText(e.Data ?? string.Empty);
                }));
            }
            catch (System.Exception x)
            {
                MessageBox.Show(x.ToString());
            }
        }
    }
}
sippybear
  • 256
  • 2
  • 6
  • But the problem is this loop blocks that function infinitely and still didn't trigger the P_OutputDataReceived event befor termination – M. Burak DÖNMEZ May 25 '18 at 20:37
  • @MehmetBurakDÖNMEZ you're right. I updated my answer to hopefully be of some use. – sippybear May 29 '18 at 17:36
  • @slippybear thanks for help but still no luck, when i run an app which has an while True loop in it, never shows its output. If it has no while true in it, then it still waits till the process returns – M. Burak DÖNMEZ May 31 '18 at 11:24