I'm using the following vb.net code to run an external command line application and read back its output:
Public Shared Function Execute(ByVal command As String, ByVal params As String, ByVal workingdir As String) As String
psi = New ProcessStartInfo(command)
psi.WorkingDirectory = workingdir
psi.RedirectStandardOutput = True
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.UseShellExecute = False
psi.CreateNoWindow = True
psi.Arguments = params
proc = Process.Start(psi)
Dim myOutput = proc.StandardOutput
proc.WaitForExit() 'Problem is here!!!!!!
Dim ret = myOutput.ReadToEnd
Return ret
End Function
This code has worked perfectly for several applications... until now. The problem is this: I'm now using it to run "aapt.exe" (a tool that gives you info on android apk applications) on a bunch o files, and the code gets stuck (never returns) in the point I commented but only on 3 particular files out of a total of 81
Of course my first thought was that the external program was failing/getting stuck on those particular files, but I tested the same command manually from a command prompt and it works perfectly! Furthermore: i added a timeout to the code, like this:
proc.WaitForExit(10000)
And in this case the process returns (obviously) but what is interesting is that the output is correct and complete! This implies that the external program is running correctly until the end, so why doesn't the process return on its own?? Is there any feasible way to debug this?
Thanks
EDIT: After hours of testing, I came to the conclusion that the problem lies in the "RedirectStandardOutput" option. No matter which order I execute/read it it hangs on some executions. I didn't find a proper solution to this, I implemented a (horrible) workaround where I disable stdout redirection and instead output the stdout to a file, then immediately re-read it in my code when the process terminates (it does terminate properly this way at least). Not an elegant solution, and I'd still like to get to the bottom of this, so I'm leaving the question open if anyone has better ideas than mine.
I think you probably just need to call
Dim ret = myOutput.ReadToEnd
beforeproc.WaitForExit()
. MSDN warns about a deadlock from calling WaitForExit() first: "A deadlock condition can result if the parent process calls p.WaitForExit before p.StandardOutput.ReadToEnd and the child process writes enough text to fill the redirected stream. The parent process would wait indefinitely for the child process to exit. The child process would wait indefinitely for the parent to read from the full StandardOutput stream." So I'm guessing those 3/81 files just have more output than the others.