Reputation: 414
I'm trying to redirect standard and error output in F#
let RunProcess (processInfo : ProcessStartInfo) =
let str = StringBuilder()
processInfo.UseShellExecute <- false
processInfo.RedirectStandardOutput <- true
processInfo.RedirectStandardError <- true
let p = new Process()
p.StartInfo <- processInfo
p.OutputDataReceived.Add(fun x -> str.Append(x.Data + Environment.NewLine) |> ignore)
p.ErrorDataReceived.Add(fun x -> str.Append(x.Data + Environment.NewLine) |> ignore)
p.Start() |> ignore
p.BeginOutputReadLine()
p.BeginErrorReadLine()
str.ToString()
When I do that nothing happen.
However when I set processInfo.RedirectStandardOutput to false things are displayed in my console.
Upvotes: 1
Views: 287
Reputation: 5004
This is what I use:
let inline tee f v = f v ; v
let inline (|>!) v f = f v ; v
let RunProcess (startInfo : ProcessStartInfo) =
let bufferOutput = new StringBuilder()
let bufferError = new StringBuilder()
let dataHandler handler = DataReceivedEventHandler(fun sender args -> try handler args.Data with _ -> ())
let consume (sb: StringBuilder) = sb.ToString() |>! (fun _ -> sb.Clear() |> ignore)
let append (sb: StringBuilder) txt = sb.Append(txt + "\n") |> ignore
let outputHandler = append bufferOutput |> dataHandler
let errorHandler = append bufferError |> dataHandler
startInfo.RedirectStandardInput <- true
startInfo.RedirectStandardOutput <- true
startInfo.RedirectStandardError <- true
startInfo.UseShellExecute <- false
let proc = new Process(
StartInfo = startInfo
, EnableRaisingEvents = true )
outputHandler |> proc.OutputDataReceived.AddHandler
errorHandler |> proc.ErrorDataReceived .AddHandler
let r = proc.Start ()
do proc.BeginOutputReadLine ()
do proc.BeginErrorReadLine ()
do proc.WaitForExit ()
let output = (consume bufferOutput).Trim()
let error = (consume bufferError ).Trim()
((if proc.HasExited then proc.ExitCode else -99999), output, error)
Upvotes: 2
Reputation: 1427
Process.Start()
does not wait for the started process to finish execution.
An additional WaitForExit
would be required to do that otherwise chances are high you are going to call the StringBuilder ToString before anything has been written to it at all.
Upvotes: 1