可以输出流程

时间:2015-09-16 12:58:20

标签: c#

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

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

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

在这种情况下,该过程似乎更新了它所写的相同行(这怎么可能?),因此它将15%,15%的更改写入18%,依此类推。只有在执行结束时,似乎才将数据刷新到StandardOutput。

此外,如果我只是尝试将数据传输到文本文件(例如odb.exe >> output.txt),它什么都不显示。

有没有办法获取临时数据?

问题不在于获得标准输出,这可以正常工作(同步和异步)。它是关于如何从一个我无法改变的过程中获得输出,而这似乎并没有将它输出到标准流中。

2 个答案:

答案 0 :(得分:0)

我认为这正是您所寻找的:C# : Redirect console application output : How to flush the output?

如果我错了,请告诉我。

答案 1 :(得分:0)

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

祝你好运!