C#让运行流程标准化

时间:2018-05-25 18:36:12

标签: c# process background-process

我有一个运行后台进程的应用程序,我需要在执行期间显示该应用程序的标准,就像实时一样。我尝试了process.OutputDataReceived,但是在后台进程终止后触发了它。但是当进程创建输出时,我需要显示标准输出。

仅供参考:我重定向了标准输出并设置了UseShellExecute false

以下是我对该流程所做的全面更改:

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();

我的活动:

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

此外,我尝试使用python文件,它的可执行版本和C文件可执行文件,但所有这些都是相同的结果。

编辑:我尝试了this解决方案,但又获得了相同的结果

**更新04.06.2018:**我刚刚发现当应用程序等待标准输入时,P_OutputDataReceived事件也被触发,但仍无法找到实时触发该事件的方法

2 个答案:

答案 0 :(得分:0)

由于执行的进程也是一个不同的线程,您需要返回UI线程以显示该进程的数据。这可以使用Invoke方法实现,如下所示:

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;
}

答案 1 :(得分:0)

我的第一个回答是错误的,没用。对于那个很抱歉。这是一个Windows窗体示例,用于如何通过按下按钮调用应用程序(Robocopy.exe)并将输出实时重定向到主窗体上的TextBox。

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());
            }
        }
    }
}