外部命令行进程永远不会返回

时间:2013-08-27 16:41:00

标签: .net vb.net command-line aapt

我正在使用以下vb.net代码来运行外部命令行应用程序并回读其输出:

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

此代码完美适用于多个应用程序......直到现在。 问题是这样的:我现在用它来运行“aapt.exe”(一个工具,它给你提供关于android apk应用程序的信息)在一堆o文件上,并且代码在我评论的点上被卡住(永不返回)但仅限于总共81个

中的3个特定文件

当然我的第一个想法是外部程序失败/卡在那些特定文件上,但我从命令提示符手动测试了相同的命令,它完美地工作! 此外:我在代码中添加了一个超时,如下所示:

    proc.WaitForExit(10000)

在这种情况下,进程返回(显然),但有趣的是输出正确且完整!这意味着外部程序正常运行直到结束,为什么不呢?这个过程自己回归?有没有可行的方法来调试它?

由于

编辑: 经过几个小时的测试,我得出结论,问题在于“RedirectStandardOutput”选项。无论我执行/读取它的顺序,它都会挂起一些执行。我没有找到适当的解决方案,我实现了一个(可怕的)解决方法,我禁用了stdout重定向,而是将stdout输出到文件,然后在进程终止时立即在我的代码中重新读取它(它确实正确终止)这样至少)。这不是一个优雅的解决方案,而且我仍然想深究这一点,所以如果有人有比我更好的想法,我就会把问题留下来。

2 个答案:

答案 0 :(得分:1)

我想您可能只需要在Dim ret = myOutput.ReadToEnd之前致电proc.WaitForExit()MSDN首先调用WaitForExit()来警告死锁:“如果父进程在p.StandardOutput.ReadToEnd之前调用p.WaitForExit并且子进程写入足够的文本来填充重定向的流,则可能导致死锁情况。父进程将无限期地等待子进程退出。子进程将无限期地等待父进程从完整的StandardOutput流中读取。“所以我猜这些3/81文件只有比其他文件更多的输出。

答案 1 :(得分:0)

您是否尝试将/ C参数添加到结尾,以便退出后返回。 例如cmd / C“”abc.exe“”

这里“/ C”非常重要,它告诉命令提示符在完成后退出。