我正在尝试重定向控制台应用程序的stdin和stdout,以便可以通过F#与它们进行交互。但是,取决于控制台应用程序,显而易见的代码似乎失败了。以下F#代码适用于dir
,但对于python
和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。
这与使用readline的python和fsi有关吗,还是我犯了一个明显的错误?是否有解决方法可以使我与F#中的fsi或python REPL进行交互?
最佳答案
这就是您要查找的代码(我很方便地在第9章,脚本编写;)如前所述,ReadLine会阻塞直到有一行完整的行导致所有的挂起。最好的选择是挂接到OutputDataRecieved事件。
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> ")
关于c# - 在.Net中重定向stdin和stdout,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1788279/