C#的ProcessStartInfo读取输出"生活" (同时) [英] C# ProcessStartInfo read Output "live" (Concurrent)

查看:185
本文介绍了C#的ProcessStartInfo读取输出"生活" (同时)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个仅运行一个选择的.bat文件控制台包装WPF图形用户界面,我希望能够查看从.bat文件活的任何输出(就好像它是运行CMD)。



我看着OutputDataReceived和事件处理这追加的文本,然后发送到这个画面,但它还是等到过程结束出现任何东西之前在屏幕上。



我如何得到输出从蝙蝠出现在实时?



< HR>

我的代码Snippits到目前为止(这是一种形式):



的形式有一个按钮()和一个多行文本字段(的textarea )。

 私人无效go_Click(对象发件人,EventArgs五)
{
ExecuteCommand();
}

公共无效ExecuteCommand()
{

INT的ExitCode;
的ProcessStartInfo ProcessInfo;
处理流程;

// ProcessInfo =新的ProcessStartInfo(cmd.exe的,/ C Z:\foo.bat);
ProcessInfo =新的ProcessStartInfo(@Z:\foo.bat); ;

ProcessInfo.CreateNoWindow = TRUE;
ProcessInfo.UseShellExecute = FALSE;

ProcessInfo.RedirectStandardError = TRUE;
ProcessInfo.RedirectStandardOutput = TRUE;

=处理新的Process();
Process.StartInfo = ProcessInfo;

Process.OutputDataReceived + =新DataReceivedEventHandler(OutputToTextArea);

的Process.Start();

//开始排序输出流的异步读取。
Process.BeginOutputReadLine();

Process.WaitForExit();

的ExitCode = Process.ExitCode;
Process.Close();
}

私人INT numOutputLines = 0;
私人无效OutputToTextArea(对象sendingProcess,DataReceivedEventArgs轮廓)
{
//收集sort命令的输出。
如果(String.IsNullOrEmpty(outLine.Data)!)
{
numOutputLines ++;

this.AppendToTextArea([+ numOutputLines.ToString()+ - + outLine.Data + Environment.NewLine);
}
}

私人无效AppendToTextArea(字符串s)
{
如果(this.textArea.InvokeRequired)
{
//这是在不同的线程,所以使用调用。
this.BeginInvoke(新MethodInvoker(()=> textArea.AppendText(S)));
}其他{
textArea.AppendText(S);
}
}



凡我foo.bat只是一个for循环:

  ECHO OFF 

FOR / L %% I IN(1,1,10)DO(
回声%%我
平-n 2 127.0.0.1> NUL


< DIV CLASS =h2_lin>解决方案

好耶,你当前阻止主线程(这是UI线程),你等待的过程中退出 ExecuteCommand ,这是直接从UI线程调用(在 go_Click )。



刚刚开始新的线程(或使用线程池)(的WinForms示例):

 私人无效的button1_Click(对象发件人,EventArgs五)
{
ThreadPool.QueueUserWorkItem(新WaitCallback(this.ExecuteCommand));
}

公共无效ExecuteCommand(对象状态)
{

}

如果你使用WPF,你可能想使用的 的BackgroundWorker


I'm trying to write a Console wrapper WPF gui that simply runs a selection of .bat files, I'd like to be able to view any output from the .bat files "live" (as if it were running in cmd).

I've looked into OutputDataReceived and event handlers which append text and then sent this to the screen, however it still waits until the Process has finished before anything appears on the screen.

How do I get the output from the .bat to appear in "real time"?


Snippits of my code so far (this is in a form):

The form has one button (go) and one multi-line text field (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);
    }
}

Where my foo.bat is just a for loop:

ECHO OFF

FOR /L %%i IN (1,1,10) DO (
   echo %%i
   ping -n 2 127.0.0.1 >nul
)

解决方案

Well yeah, you're currently blocking the main thread (which is the UI thread) as you wait for process exit in ExecuteCommand, which is directly called from the UI thread (in go_Click).

Just start a new thread (or use a ThreadPool) (Winforms example):

private void button1_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(this.ExecuteCommand));
}

public void ExecuteCommand(object state)
{
    ...
}

If you're using WPF, you probably want to use a BackgroundWorker.

这篇关于C#的ProcessStartInfo读取输出&QUOT;生活&QUOT; (同时)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆