2013-08-27 1 views
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) в файлах с пучком o, и код застревает (никогда не возвращается) в точке I прокомментировал, но только на 3 отдельных файлы из в общей сложности 81

конечно, моя первая мысль была о том, что внешняя программа терпела неудачу/застрять на этих конкретные файлы, но я тестировал ту же команду вручную из командной строки и он отлично работает! Кроме того: я добавил таймаут к коду, например:

proc.WaitForExit(10000) 

И в этом случае возвращается процесс (очевидно), но интересно то, что выход правильный и полный! Это означает, что внешняя программа работает правильно до конца, так почему же процесс не возвращается самостоятельно? Есть ли возможный способ отладки этого?

Благодаря

EDIT: После нескольких часов тестирования, я пришел к выводу, что проблема лежит в опции «RedirectStandardOutput». Независимо от того, какой заказ я выполняю/читаю, он зависает при некоторых исполнениях. Я не нашел подходящего решения для этого, я применил (ужасное) обходное решение, в котором я отключил перенаправление stdout и вместо этого вывел stdout в файл, а затем сразу же перечитал его в моем коде, когда процесс завершается (он заканчивается правильно таким образом, по крайней мере). Не изящное решение, и мне все равно хотелось бы разобраться в этом, поэтому я оставляю вопрос открытым, если у кого-то есть лучшие идеи, чем у меня.

+0

Вы пытались запустить программу на одном из этих проблемных файлов (из командной строки), чтобы узнать, отличается ли его поведение от того, когда он запускается с одним из файлов без проблем? Возможно, программа висит после выполнения всей обработки. –

+0

@Jim: да, прочитайте все мои вопросы, как я уже сказал: отлично работает из командной строки. –

+0

Каковы имена файлов, которые не выполняются? Являются ли эти имена файлов переданными в аргументе 'params'? – Matt

ответ

1

Я думаю, вам, вероятно, просто нужно позвонить Dim ret = myOutput.ReadToEnd до proc.WaitForExit(). MSDN предупреждает о блокировке вызова WaitForExit(): «Условие блокировки может возникнуть, если родительский процесс вызывает p.WaitForExit до p.StandardOutput.ReadToEnd, а дочерний процесс записывает достаточно текста для заполнения перенаправленного потока. Родительский процесс будет ждать на неопределенный срок для завершения дочернего процесса. Детский процесс будет бесконечно ждать, пока родитель не прочитает полный поток StandardOutput ». Поэтому я предполагаю, что эти 3/81 файлы имеют больше выходных данных, чем другие.

+0

Нет, это не проблема, я попытался инвертировать и это то же самое. Кроме того: есть еще несколько файлов, которые генерируют больше выходных данных, чем проблемные три. –

0

Вы пробовали добавить параметр/C в конец, чтобы он вернулся после выхода. , например. cmd/C "" abc.exe ""

Здесь «/ C» важно, чтобы он сообщал командной строке, чтобы выйти после ее завершения.