我正在尝试编写一个控制台包装器 WPF gui,它只运行一系列 .bat 文件,我希望能够“实时”查看 .bat 文件的任何输出(就像它在命令)。
我研究了 OutputDataReceived 和事件处理程序,它们附加文本然后将其发送到屏幕,但它仍然会等到进程完成后屏幕上才会显示任何内容。
如何让 .bat 的输出“实时”出现?
到目前为止我的代码片段(这是一种形式):
表单有一个按钮(go
)和一个多行文本字段(textArea
)。
private void go_Click(object sender, EventArgs e)
{
ExecuteCommand();
}
public void ExecuteCommand()
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
//ProcessInfo = new ProcessStartInfo("cmd.exe", "/C z:\foo.bat");
ProcessInfo = new ProcessStartInfo(@"z:\foo.bat"); ;
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
ProcessInfo.RedirectStandardError = true;
ProcessInfo.RedirectStandardOutput = true;
Process = new Process();
Process.StartInfo = ProcessInfo;
Process.OutputDataReceived += new DataReceivedEventHandler(OutputToTextArea);
Process.Start();
// Start the asynchronous read of the sort output stream.
Process.BeginOutputReadLine();
Process.WaitForExit();
ExitCode = Process.ExitCode;
Process.Close();
}
private int numOutputLines = 0;
private void OutputToTextArea(object sendingProcess, DataReceivedEventArgs outLine)
{
// Collect the sort command output.
if (!String.IsNullOrEmpty(outLine.Data))
{
numOutputLines++;
this.AppendToTextArea("[" + numOutputLines.ToString() + "] - " + outLine.Data + Environment.NewLine);
}
}
private void AppendToTextArea(string s)
{
if (this.textArea.InvokeRequired)
{
// It's on a different thread, so use Invoke.
this.BeginInvoke (new MethodInvoker(() => textArea.AppendText(s)));
} else {
textArea.AppendText(s);
}
}
我的 foo.bat 只是一个 for 循环:
ECHO OFF
FOR /L %%i IN (1,1,10) DO (
echo %%i
ping -n 2 127.0.0.1 >nul
)
最佳答案
是的,您当前正在阻塞主线程(即 UI 线程),因为您在 ExecuteCommand
中等待进程退出,这是直接从 UI 线程调用的(在 go_Click
).
只需启动一个新线程(或使用ThreadPool
)(Winforms 示例):
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.ExecuteCommand));
}
public void ExecuteCommand(object state)
{
...
}
如果您使用的是 WPF,您可能希望使用 BackgroundWorker
.
关于C# ProcessStartInfo 读取输出 "live"(并发),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14582794/