捕获奇怪进程的实时标准输出(例如:7za.exe,PsExec.exe)

20 浏览
0 Comments

捕获奇怪进程的实时标准输出(例如:7za.exe,PsExec.exe)

我已经成功地在几种编程语言中捕获了许多命令行工具的实时标准输出(和错误输出),但是有一些工具我无法让其正常工作。

这些工具包括:

  • 7za.exe(7-Zip的一部分)
  • PsExec.exe(Sysinternals的一部分)

下面的代码示例可以正常打印大多数命令行工具(例如robocopy)的实时进度。

然而,“7za.exe b”首先会运行完整的基准测试,然后一次性打印所有标准输出(即非实时)。

如果在cmd提示符中运行相同的命令,则可以看到基准测试在进行时会打印到控制台。

我尝试过刷新、同步、异步、为子进程创建无缓冲输出流,以及C#和Python两种语言的大部分尝试,但都没有成功。

namespace ConsoleApp
{
    class Program
    {
        static void Main()
        {
            var process = new System.Diagnostics.Process
            {
                StartInfo = new System.Diagnostics.ProcessStartInfo
                {
                    FileName = "7za.exe",
                    Arguments = "b",
                    UseShellExecute = false,
                    RedirectStandardOutput = true
                }
            };
            process.OutputDataReceived += (sender, args) => System.Console.WriteLine(args.Data);
            process.Start();
            process.BeginOutputReadLine();
            process.WaitForExit();
        }
    }
}

我快速查看了7-Zip的源代码,但没有发现任何异常之处。

以下是7-Zip大致执行的操作:

CStdOutStream g_StdOut(stdout);
CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
CStdOutStream &so = g_StdOut;
FILE* _file = (FILE*)so;
fputs("blah", _file)

我还注意到了一些其他事情...

在Cygwin中运行“7za.exe b”也不会在基准测试完成之前打印任何进度。

ConEmu能够打印实时输出,但是调试其代码并阅读文档未能揭示其工作原理。我认为它与“Windows Console”(而不是cmd.exe)和CSRSS有关。

0