我有一个第三方DOS进程,它将有关其进度的数据写入命令行.我想对进展做出反应.通常我会用一个Process带RedirectStandardOutput = true和RedirectStandardError = true再
.OutputDataReceived +=xyzOutputDataReceived;
.ErrorDataReceived += xyzErrorDataReceived;
.Start();
.BeginOutputReadLine();
.BeginErrorReadLine();
Run Code Online (Sandbox Code Playgroud)
通常这是有效的.我得到了我需要的DataReceivedEventArg.
在这种情况下,该过程似乎更新了它所写的相同行(这怎么可能?),因此它将15%,15%的更改写入18%,依此类推.只有在执行结束时,似乎才将数据刷新到StandardOutput.
此外,如果我只是尝试将数据传输到文本文件(例如odb.exe >> output.txt),它什么都不显示.
有没有办法获取临时数据?
问题不在于获得标准输出,这可以正常工作(同步和异步).它是关于如何从一个我无法改变的进程中获取输出,并且似乎没有将它的输出刷新到标准流.
就像 juharr 所说,您需要使用 Win32 来屏幕抓取控制台。幸运的是,您不需要自己编写该代码。您可以使用这篇文章中的缓冲区读取器:/sf/answers/865641521/
BufferReader 从标准输出读取。我想您正在编写 wpf 或 winforms 应用程序,因此我们还必须获得对 DOS 应用程序的控制台窗口的引用。为此,我们将使用 Win32 API 调用 AttachConsole。
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AttachConsole(int pid);
Run Code Online (Sandbox Code Playgroud)
我编写了一个小示例程序来演示其用法。它启动 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);
}
Run Code Online (Sandbox Code Playgroud)
祝你好运!
| 归档时间: |
|
| 查看次数: |
550 次 |
| 最近记录: |