重定向.Net中的stdin和stdout

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

 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> ") 

我敢打赌,python和fsi实际上都不会生成一行要读取的文本。 对ReadLine的调用将阻塞,直到以回车符或换行符结尾的整行可用。

尝试一次读取一个字符(使用Read而不是ReadLine ),看看会发生什么。

这可能是Michael Petrotta所说的。 如果是这样的话,即使阅读一个角色也无济于事。 您需要做的是使用异步版本( BeginOutputReadLine ),以便您的应用程序不会阻止。