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



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

但是现在我只在应用程序退出时接收输出。我在这里和其他网站上读了很多问题,阅读类似的问题同步捕获过程输出(即"当它发生时"),但仍然找不到解决方案。下面的代码片段:

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);
}

试试这个代码

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);
    }
}

我认为你的线程有问题,你的进程在主线程下运行,所以你的输出只会在进程完成时显示。所以你需要使用后台worker或线程,你也可以使用dispatcher从当前进程获取输出。

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

希望它对你有用。

编辑

可以使用

Assembly: WindowsBase (in WindowsBase.dll) (Ref MSDN)

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

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

最新更新