【发布时间】:2023-03-18 18:25:01
【问题描述】:
我遇到了来自控制台应用程序的重定向输出实时显示在 Winforms 文本框中的问题。消息正在逐行生成,但是一旦需要与表单进行交互,似乎什么都没有显示。
根据 Stackoverflow 和其他论坛上的许多示例,在流程完成之前,我似乎无法将流程的重定向输出显示在表单的文本框中。
通过将调试行添加到“stringWriter_StringWritten”方法并将重定向的消息写入调试窗口,我可以看到在进程运行期间到达的消息,但这些消息在进程完成之前不会出现在表单的文本框中。
感谢您对此提出的任何建议。
这是代码的摘录
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();
}
}
【问题讨论】:
标签: c# winforms redirect process console