我有一个运行后台进程的应用程序,我需要在执行期间显示该应用程序的标准,就像实时一样。我尝试了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
事件也被触发,但仍无法找到实时触发该事件的方法
答案 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());
}
}
}
}