简体   繁体   English

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

[英]Get another application standart output in realtime

I want to get output of console application in realtime (same as run via cmd.exe) by my WinForm application. 我想通过WinForm应用程序实时获取控制台应用程序的输出(与通过cmd.exe运行的输出相同)。 All actions i perform in non-UI thread (using BackgroundWorker's method bwRezerve_DoWork). 我在非UI线程中执行的所有操作(使用BackgroundWorker的方法bwRezerve_DoWork)。 AddTextToTextbox use Invoke to update UI. AddTextToTextbox使用调用来更新UI。

But now i receive output only when application is exited. 但是现在我仅在退出应用程序时收到输出。 I read a lot of question here and on other sites, read similar question Capture output of process synchronously (ie "when it happens") but still can't find solution. 我在这里和其他站点上阅读了很多问题,阅读了类似的问题同步捕获过程的输出(即“何时发生”),但仍然找不到解决方案。 Here code snippet: 这里的代码片段:

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

Also i've tried this instead of OutputDataReceived but result is the same 我也尝试过这个而不是OutputDataReceived但是结果是一样的

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

Try this code 试试这个代码

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

I think problem there is problem with your thread your process is running under main thread so your output will display only when process is completed. 我认为问题是您的线程有问题,您的进程正在主线程下运行,因此您的输出仅在进程完成时显示。 So you need use background worker or thread you can also use dispatcher to get output from current process. 因此,您需要使用后台工作程序或线程,也可以使用调度程序从当前进程获取输出。

while (!proc.StandardOutput.EndOfStream)
{

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

}

hope its work for you .. 希望它为你工作..

EDIT 编辑

you can get current dispatcher using window base Lib. 您可以使用基于窗口的库Lib获取当前的调度程序。

Assembly: WindowsBase (in WindowsBase.dll) ( Ref MSDN ) 程序集: WindowsBase(在WindowsBase.dll中)( Ref MSDN

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

7zip doesn't use standard output - you can easily see that since it continually rewrites the screen (to show the progress). 7zip不使用标准输出-您可以轻松地看到它,因为它不断重写屏幕(以显示进度)。 There's no way to stream that. 无法串流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM