如何通过stdout和stdin与进程交互

时间:2015-12-27 22:12:43

标签: .net windows process f#

我正在尝试启动F#交互式子流程,通过标准输入向其发送代码,并通过标准输出接收响应。这是我的尝试代码(命令行args只是fsi,它位于路径“):

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,但它们也没用。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我想出了如何修复它,但我并不完全理解所发生的一切。 这个答案帮助我找到了解决方案。 Redirecting stdin and stdout in .Net

诀窍是使用proc.BeginOutputReadLine()然后订阅proc.OutputDataReceived而不是调用readline。我认为这个工作的原因与它是异步的有关。