I use Process.Start to start a batch file. The batch file uses the "START" command to start several programs in parallel and then exits.
Once the batch file is done Process.HasExited becomes true and Process.ExitCode contains the correct exit code.
But when I call Process.WaitForExit() it hangs / never returns.
The following piece of code demonstrates the problem. It creates a batch file, starts it and then prints:
Process is still running... Batch file is done! Process has exited. Exit code: 123 Calling WaitForExit()...
It should then print:
… but it never does (even though HasExited is true and we already have an ExitCode).
open System.IO open System.Diagnostics open System.Threading let foobat = """ START ping -t localhost START ping -t google.com ECHO Batch file is done! EXIT /B 123 """ File.WriteAllText("foo.bat", foobat) use p = new Process(StartInfo = ProcessStartInfo("foo.bat", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true)) let onOutput = DataReceivedEventHandler(fun _ args -> printfn "%s" args.Data) p.OutputDataReceived.AddHandler onOutput p.ErrorDataReceived.AddHandler onOutput p.Start() |> ignore p.BeginErrorReadLine() p.BeginOutputReadLine() while not p.HasExited do printfn "Process is still running..." Thread.Sleep(1000) printfn "Process has exited. Exit code: %d" p.ExitCode printfn "Calling WaitForExit()..." p.WaitForExit()|> ignore printfn "WaitForExit returned."
I noticed that this only happens when the batch file contains "START" commands and when standard output and/or standard error are redirected.
Why does WaitForExit() never return?
What's the right way to wait for such a process to exit?
Is it safe to just poll Process.HasExited or can that result in other problems?
PS.: I just noticed that calling WaitForExit(100000) with a huge timeout (that definitely doesn't expire) returns immediately when the process exits. Wierd. Without timeout it hangs.