在 .Net 中重定向标准输入和标准输出 [英] Redirecting stdin and stdout in .Net

查看:31
本文介绍了在 .Net 中重定向标准输入和标准输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试重定向控制台应用程序的 stdin 和 stdout,以便我可以通过 F# 与它们交互.但是,根据控制台应用程序,明显的代码似乎失败了.以下 F# 代码适用于 dir,但对于 pythonfsi 失败(挂起):

I'm trying to redirect stdin and stdout of a console application, so that I can interact with them via F#. However, depending on the console application the obvious code seems to fail. The following F# code works for dir but fails (hangs) for python and fsi:

open System
open System.Diagnostics

let f = new Process()
f.StartInfo.FileName <- "python"
f.StartInfo.UseShellExecute <- false
f.StartInfo.RedirectStandardError <- true
f.StartInfo.RedirectStandardInput <- true
f.StartInfo.RedirectStandardOutput <- true
f.EnableRaisingEvents <- true
f.StartInfo.CreateNoWindow <- true
f.Start()
let line = f.StandardOutput.ReadLine()

这对 python 挂起,但对 dir 有效.

This hangs for python but works for dir.

这是否与使用 readline 的 python 和 fsi 有关,还是我犯了一个明显的错误?是否有解决方法可以让我从 F# 与 fsi 或 python REPL 交互?

Does this have do with python and fsi using readline or am I making an obvious mistake? Is there a work around that would allow me to interact with fsi or python REPL from F#?

推荐答案

这就是你要找的代码(我已经在第 9 章脚本编写中方便地编写了它;)如前所述,ReadLine 会阻塞直到有一行这会导致各种挂起.最好的办法是连接到 OutputDataRecieved 事件.

This is the code you are looking for (which I conveniently have written in Chapter 9, Scripting ;) As mentioned earlier, ReadLine blocks until there is a full line which leads to all sorts of hangs. Your best bet is to hook into the OutputDataRecieved event.

open System.Text
open System.Diagnostics

let shellEx program args =

    let startInfo = new ProcessStartInfo()
    startInfo.FileName  <- program
    startInfo.Arguments <- args
    startInfo.UseShellExecute <- false

    startInfo.RedirectStandardOutput <- true
    startInfo.RedirectStandardInput  <- true

    let proc = new Process()
    proc.EnableRaisingEvents <- true

    let driverOutput = new StringBuilder()
    proc.OutputDataReceived.AddHandler(
        DataReceivedEventHandler(
            (fun sender args -> driverOutput.Append(args.Data) |> ignore)
        )
    )

    proc.StartInfo <- startInfo
    proc.Start() |> ignore
    proc.BeginOutputReadLine()

    // Now we can write to the program
    proc.StandardInput.WriteLine("let x = 1;;")
    proc.StandardInput.WriteLine("x + x + x;;")
    proc.StandardInput.WriteLine("#q;;")

    proc.WaitForExit()
    (proc.ExitCode, driverOutput.ToString())

输出(可以被修饰):

val it : int * string =
  (0,
   "Microsoft F# Interactive, (c) Microsoft Corporation, All Rights ReservedF# Version 1.9.7.8, compiling for .NET Framework Version v2.0.50727For help type #help;;> val x : int = 1> val it : int = 3> ")

这篇关于在 .Net 中重定向标准输入和标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆