【问题标题】:Passing through console output from Process.Start directly直接从 Process.Start 传递控制台输出
【发布时间】:2014-01-26 17:46:29
【问题描述】:

我正在使用 .NET 命令行应用程序中的 Process.Start 来运行另一个命令行应用程序。我不想捕获应用程序的输出,我只想让它直接进入控制台。

在下面的程序中,输出似乎消失得无影无踪。如果我将CreateNoWindow 保留为默认的false,那么我会在新的控制台窗口中获得输出,但我希望它在原始控制台窗口中。 UseShellExecute <- false 也是必需的,否则 CreateNoWindow 将被强制为 false

我可以使用RedirectStandardOutputRedirectStandardError 做一些更复杂的事情,然后捕获输出并重新打印它,但这与WaitForExit 结合起来非常巧妙,特别是在我想要使用的真实应用程序中the version that has a timeout.

有什么方法可以让标准输出和错误直接通过?

我看到的行为令人困惑,因为RedirectStandardOutput 的文档似乎确实说得很清楚:

当进程将文本写入其标准流时,该文本通常会显示在控制台上。

这是演示代码。当我使用DummyRunner.exe 运行它时,我会从第一段代码中得到输出,而当我使用DummyRunner.exe DummyRunner.exe 运行它时,我什么也得不到。虽然代码在 F# 中,但据我所知,没有什么特别针对 F# 的问题。

module DummyRunner

open System
open System.Diagnostics

[<EntryPoint>]
let main args =

    // do something when called with no arguments, just so we can call
    // this with itself as an argument to make a self-contained test
    if args.Length = 0 then
        for n = 1 to 5 do
            printfn "Waiting %d" n
            System.Threading.Thread.Sleep(1000)
        System.Environment.Exit(0)

    let cmd = args.[0]
    let cmdArgs = args.[1..]

    let startInfo = ProcessStartInfo(cmd, String.Join(" ", cmdArgs))

    startInfo.UseShellExecute <- false
    startInfo.CreateNoWindow <- true

    let p = Process.Start(startInfo)

    p.WaitForExit()
    p.ExitCode

【问题讨论】:

    标签: .net f#


    【解决方案1】:

    您实际上并没有阅读您的流程的标准输出。重定向标准输出会将输出添加到进程标准输出,但不会将其读入正在运行的进程中。

    let startInfo = ProcessStartInfo(cmd, String.Join(" ", cmdArgs))
    
    startInfo.UseShellExecute <- false
    startInfo.RedirectStandardOutput <- true;
    let p = Process.Start(startInfo)
    
    printfn p.StandardOutput.ReadToEnd();
    p.WaitForExit()
    p.ExitCode
    

    这应该将运行进程的输出转发到父运行线程。有关这方面的更多信息,请参阅此页面。

    redirect std output

    【讨论】:

    • 我不想读取标准输出,我只想让它直接进入控制台。
    • 上述更改将一个进程的标准输出通过管道传输到另一个进程的标准输出,是的,从技术上讲,它确实将一个进程的输出读入另一个进程,但我不完全确定这是可能的让两个进程共享相同的 std 输出流,而无需从一个进程读取到另一个进程。可能有办法在内部做到这一点,但我怀疑进一步的研究会发现它是以相同的方式完成的
    • 为了避免死锁,您可以使读取异步,然后如果等待退出确实超时,异步调用仍然返回......
    • 我还需要交替读取标准错误 - 我不能同时在两个流上使用ReadToEnd,除非我使用多个线程。我确信我可以让事情这样运作,但它似乎相当复杂。
    • 我给你的链接中提到的 BeginOutputReadLine 方法是对被调用进程的 std 输出流的异步读取,你是对的,你不能同时使用同步读取,但你当然可以使用异步读取
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 2011-07-19
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2020-06-05
    相关资源
    最近更新 更多