实时获取另一个应用程序标准输出

时间:2016-10-12 06:33:41

标签: c# winforms process real-time stdout

我希望通过我的WinForm应用程序实时输出控制台应用程序(与通过cmd.exe运行相同)。我在非UI线程中执行的所有操作(使用BackgroundWorker的方法bwRezerve_DoWork)。 AddTextToTextbox使用Invoke更新UI。

但现在我只在申请退出时收到输出。 我在这里和其他网站上阅读了很多问题,阅读类似的问题Capture output of process synchronously (i.e. "when it happens"),但仍无法找到解决方案。 这里是代码片段:

private void bwRezerve_DoWork(object sender, DoWorkEventArgs e)
{
    proc = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = Application.StartupPath + Path.DirectorySeparatorChar + "7z.exe",
            Arguments = e.Argument,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true,
        }
    };
    proc.EnableRaisingEvents = true;
    proc.OutputDataReceived += (who, what) => AddTextToTextbox(what.Data);
    proc.ErrorDataReceived += (who, what) => AddTextToTextbox(what.Data);

    proc.Start();
    proc.BeginOutputReadLine();
    proc.BeginErrorReadLine();
    //same result with next line commented
    proc.WaitForExit(5 * 60 * 1000);
}

我也试过这个而不是OutputDataReceived,但结果是相同的

while (!proc.StandardOutput.EndOfStream)
{
    string line = proc.StandardOutput.ReadLine();
    AddTextToTextbox(line);
}

3 个答案:

答案 0 :(得分:1)

试试此代码

private void bwRezerve_DoWork(object sender, DoWorkEventArgs e)
{
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = Application.StartupPath + Path.DirectorySeparatorChar + "7z.exe";
    psi.Arguments = e.Argument;
    psi.UseShellExecute = false;
    psi.RedirectStandardError = true;
    psi.RedirectStandardOutput = true;
    psi.CreateNoWindow = true;

    Process proc = Process.Start(psi);
    proc.WaitForExit();

    while (!proc.StandardOutput.EndOfStream)
    {
       string line = proc.StandardOutput.ReadLine();
       AddTextToTextbox(line);
    }
}

答案 1 :(得分:1)

我认为问题是您的进程在主线程下运行的线程存在问题,因此只有在进程完成时才会显示输出。 因此,您需要使用后台工作程序或线程,您也可以使用调度程序从当前进程获取输出。

while (!proc.StandardOutput.EndOfStream)
{

  Application.Current.Dispatcher.Invoke(new Action(() =>
     {
    string line = proc.StandardOutput.ReadLine();
    AddTextToTextbox(line);
     }), null);

}

希望它为你工作..

修改

你可以使用当前的调度员 window base Lib。

汇编: WindowsBase(在WindowsBase.dll中)(Ref MSDN

System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
            {
                string line = proc.StandardOutput.ReadLine();
                AddTextToTextbox(line);
            }), null);

答案 2 :(得分:0)

7zip没有使用标准输出 - 你可以很容易地看到它,因为它不断重写屏幕(显示进度)。没有办法传播它。