可能得到一个过程的输出

本文关键字:一个 过程 输出 | 更新日期: 2023-09-27 18:13:03

我有一个第三方DOS进程,它将有关其进度的数据写入命令行。我想对进展做出反应。通常我会使用Process, RedirectStandardOutput = trueRedirectStandardError = true,然后是

.OutputDataReceived +=xyzOutputDataReceived; 
.ErrorDataReceived += xyzErrorDataReceived;
.Start();
.BeginOutputReadLine();
.BeginErrorReadLine();

通常这是有效的。我得到了我需要的作为DataReceivedEventArg。

在这种情况下,进程似乎更新了它所写的同一行(这怎么可能?),所以它写入15%,15%更改为18%,等等。只有在执行结束时,数据才会刷新到StandardOutput。

如果我只是尝试管道数据到一个文本文件(如odb.exe >> output.txt),它显示什么。

是否有办法获得临时数据?

问题不是关于获得标准输出,这工作得很好(同步和异步)。这是关于如何从我无法改变的过程中获得输出,并且似乎不会将其输出刷新到标准流。

可能得到一个过程的输出

就像juharr说的,您需要使用Win32来对控制台进行屏幕抓取。幸运的是,您不需要自己编写这些代码。您可以使用这篇文章中的缓冲阅读器:https://stackoverflow.com/a/12366307/5581231

BufferReader从standardout读取数据。我猜您正在编写wpf或winforms应用程序,因此我们还必须获得对DOS应用程序的控制台窗口的引用。为此,我们将使用Win32 API调用AttachConsole。

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AttachConsole(int pid);
我写了一个小的示例程序来演示它的用法。它启动exe并连接到它的控制台。然后,它每秒擦除整个窗口一次,并将输出转储到调试器输出窗口。您应该能够修改它来搜索控制台内容的任何关键字等,您可以使用它来跟踪程序的进度。或者你可以将其转储到文本框或UI中的其他地方,可能是在比较更改之后?
var process = Process.Start(@"..path to your exe....");       
//Wait for the DOS exe to start, and create its console window
while (process.MainWindowHandle == IntPtr.Zero)
{
  Thread.Sleep(500);
}
//Attach to the console of our DOS exe
if (!AttachConsole(process.Id))
  throw new Exception("Couldn't attach to console");
while (true)
{
  var strings = ConsoleReader.ReadFromBuffer(0, 0,  
                    (short)Console.BufferWidth, 
                     short)Console.BufferHeight);
  foreach (var str  in strings.
                     Select(s => s?.Trim()).
                     Where(s => !String.IsNullOrEmpty(s)))
 {
    Debug.WriteLine(str);          
 }
 Thread.Sleep(1000);
}

祝你好运!