Как перенаправить стандартный и вывод ошибок в F # - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь перенаправить стандартный вывод ошибок в 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()

Когда я это делаю, ничего не происходит.

Однако, когда я устанавливаю для processInfo.RedirectStandardOutput значение false, отображаютсямоя консоль.

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Вот что я использую:

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)
0 голосов
/ 02 февраля 2019

Process.Start() не ожидает, пока запущенный процесс завершит выполнение.Для этого потребуется дополнительная WaitForExit, в противном случае высока вероятность того, что вы вызовете StringBuilder ToString, прежде чем что-либо будет записано в него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...