Ответ 1
Код, который вы написали в том виде, в котором вы его написали (почти) ok: process.Start запустите процесс, который вы указали, ну, а другой процесс, поэтому ваши выходные данные будут повторяться параллельно с выполнением вашего процесса. Одна проблема заключается в том, что вы должны бросить вызов process.WaitForExit в конце - тот факт, что выходной поток закрыт, не означает, что процесс завершен.
Однако вы столкнетесь с проблемами с синхронным чтением, если попытаетесь прочитать как stdout, так и stderr процесса: нет возможности для чтения двух потоков синхронно и одновременно - вы будете заторможены, если будете читать stdout, а процесс записывается в stderr и ждет, когда вы будете потреблять его выход или наоборот.
Чтобы оповестить об этом, вы можете подписаться на OutputDataRecieved и ErrorDataRecieved, например:
type ProcessResult = { exitCode : int; stdout : string; stderr : string }
let executeProcess (exe,cmdline) =
let psi = new System.Diagnostics.ProcessStartInfo(exe,cmdline)
psi.UseShellExecute <- false
psi.RedirectStandardOutput <- true
psi.RedirectStandardError <- true
psi.CreateNoWindow <- true
let p = System.Diagnostics.Process.Start(psi)
let output = new System.Text.StringBuilder()
let error = new System.Text.StringBuilder()
p.OutputDataReceived.Add(fun args -> output.Append(args.Data) |> ignore)
p.ErrorDataReceived.Add(fun args -> error.Append(args.Data) |> ignore)
p.BeginErrorReadLine()
p.BeginOutputReadLine()
p.WaitForExit()
{ exitCode = p.ExitCode; stdout = output.ToString(); stderr = error.ToString() }
Вы также можете написать что-то по строкам:
async {
while true do
let! args = Async.AwaitEvent p.OutputDataReceived
...
} |> Async.StartImmediate
для обработки реактивных событий в режиме F #.