1

我正在使用以下 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 应用程序信息的工具),并且代码在我评论的地方卡住(永远不会返回)但仅针对总共 81 个文件中的 3 个特定文件

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

    proc.WaitForExit(10000)

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

谢谢

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

4

2 回答 2

1

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

于 2013-08-27T17:22:10.140 回答
0

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

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

于 2014-04-30T06:51:51.807 回答