我试图启动一个F#交互子程序,通过标准输入向它发送代码,并通过标准输出接收响应。这是我尝试(在命令行参数只是fsi
,这是道路上“)的代码:。如何通过stdout和标准输入与进程进行交互
let readStrStream (stream : StreamReader) =
let buffer = Array.create 1024 (char 0)
let bytesReceived = stream.Read(buffer, 0, 1024)
let chars = buffer |> Array.take bytesReceived
let str = String.Concat(chars)
str
let rec loop (proc : Process) = async {
proc.StandardInput.WriteLine("printf \"iteration\"")
let output = readStrStream proc.StandardOutput
printfn "%s" output
let error = readStrStream proc.StandardError
printfn "%s" error
return! loop proc }
let start proc =
Async.Start(loop proc, cancellationToken = cts.Token)
{ new IDisposable with member x.Dispose() = cts.Cancel }
[<EntryPoint>]
let main argv =
let procStart = new ProcessStartInfo(argv.[0], argv.[1..] |> String.concat " ")
procStart.UseShellExecute <- false
procStart.RedirectStandardInput <- true
procStart.RedirectStandardOutput <- true
procStart.RedirectStandardError <- true
procStart.WorkingDirectory <- "C:\\Users\\Philip"
let proc = Process.Start(procStart)
proc.StandardInput.AutoFlush <- true
let x = start proc
let y = Console.ReadLine()
0
此代码不能正常工作当我运行它,它只是打印2个换行符
如果我改变,像这样的代码,
let proc = Process.Start(procStart)
Thread.Sleep(10000)
程序打印出
Microsoft (R) F# Interactive version 14.0.23020.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
>
这是fsi
的启动文本。
我做了一些调试,这里是我发现的。 在第一个代码中,在第一次迭代中,两个对readStrStream
的调用返回\r\n
,在第二次迭代中,他们首先调用挂起。
在第二个代码中,该调用返回fsi
输出。
在我看来,由于某种原因,一个电话打到stream.Read
后,流正在关闭。
我一直在玩fsi以外的其他东西,比如python或者irb,但是它们也没有工作。
我该如何解决这个问题?
来自内存旧版本(可能还有新版本)使用奇怪的事件循环来读取可能绕过标准输入的输入。无论如何,你想在这里做什么? –
@JohnPalmer在这里的代码,我试图一遍又一遍地发送一行代码。我最终想做一个广义的repl。 – phil
我想你想要https://github.com/fsharp/FSharp.Compiler.Service –