【问题标题】:How can I copy the stdout of a process (copy, not redirect)?如何复制进程的标准输出(复制,而不是重定向)?
【发布时间】:2011-10-21 22:16:42
【问题描述】:

有很多例子展示了如何重定向另一个应用程序的标准输出。但是我想让应用程序保留它的标准输出,并且只在我的父进程中检索标准输出的副本。这可能吗?

我的场景:我有一些测试(使用 Visual Studio Test Runner)启动一个外部进程(服务器)来进行测试。服务器在其标准输出中输出了很多有用的调试信息,我想将这些信息包含在我的测试结果中。

我可以捕获进程输出并通过 Trace.WriteLine 将其输出,以便稍后显示在测试详细信息中。但是,最好在测试运行时查看服务器窗口及其输出以查看当前进度(测试可能会运行很长时间)。

所以我正在寻找方法来复制这些信息,而不是简单地重定向它。

有什么想法吗?

【问题讨论】:

  • 嗯,也许 Echo/Tee 流可能会有所帮助? codeproject.com/KB/dotnet/echostream.aspx(google 'c# tee stream' 更多点击)
  • 不确定,因为我无法在这里进行测试,但 Process.OutputDataReceived 事件可能会为您提供所需的行为,请参阅:msdn.microsoft.com/en-us/library/…
  • OutputDataReceived 是我正在使用的,但它需要流重定向,因此会从服务器控制台窗口中删除输出...

标签: c# .net unit-testing mstest stdout


【解决方案1】:

这对你有用吗?

        var outputText = new StringBuilder();
        var errorText = new StringBuilder();

        using (var process = Process.Start(new ProcessStartInfo(
            @"YourProgram.exe",
            "arguments go here")
            {
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                UseShellExecute = false
            }))
        {
            process.OutputDataReceived += (sendingProcess, outLine) =>
            {
                outputText.AppendLine(outLine.Data); // capture the output
                Console.Out.WriteLine(outLine.Data); // echo the output
            }

            process.ErrorDataReceived += (sendingProcess, errorLine) =>
            {
                errorText.AppendLine(errorLine.Data); // capture the error
                Console.Error.WriteLine(errorLine.Data); // echo the error
            }

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
            // At this point, errorText and outputText StringBuilders
            // have the captured text.  The event handlers already echoed the
            // output back to the console.
        }

【讨论】:

  • 这个。通过重定向到复合输出类来复制控制台输出,该复合输出类会将输出“广播”到多个“侦听器”。有很多模式;这可能是实现起来不太复杂的一种。
  • 问题在于,此代码作为 microsoft Visual Studio 测试运行程序内的单元测试的一部分运行。测试运行器本身没有控制台窗口...
【解决方案2】:

编写一个将 STDIN 转发到 STDOUT 的小程序,同时用它做其他事情怎么样?

然后,您可以将启动服务器进程的命令替换为启动它并将其输出通过管道传输到上述实用程序的命令。这样您就可以通过编程方式访问输出并在输出窗口中实时查看。

【讨论】:

  • 是的,这是一个解决方案,我考虑过,只是在我的测试中使用似乎有点矫枉过正。我希望有一个更简单的解决方案。另一个(小)缺点是我的服务器正在使用在转发器应用程序中不可见的彩色输出。
  • 我认为显示服务器窗口的小好处不足以使我的测试代码进一步复杂化。但是,您的想法可以通过一些小的修改来实现:在测试代码中捕获我的服务器的输出并将其发送到这个“echo”程序,该程序只会在控制台中显示它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 2011-01-10
  • 2010-09-21
  • 1970-01-01
  • 2013-06-02
相关资源
最近更新 更多