
Я видел много вопросов на stackoverflow и других ресурсах о том как запустить процесс и получить его вывод. Правильно использовать System.Diagnostics.Process
не так просто, и чаще всего это делается неправильно.
Некоторые общие ошибки с System.Diagnostics.Process
:
- Отсутствие перехвата обоих выходных потоков (error & output)
- Отсутствие перенаправления ввода (input) может привести к зависанию приложения
- Отсутствие закрытия перенаправленного ввода может привести к зависанию приложения
- Отсутствие вызова
BeginOutputReadLine
/BeginErrorReadLine
при использовании событий - Использование
OutputDataReceived
/ErrorDataReceived
без ожиданияnull
- Отсутствие проверки на
null
в обработчиках событийOutputDataReceived
/ErrorDataReceived
- Забывание установить
EnableRaisingEvents
=true
при использовании событияExited
- Забывание настроек
ErrorDialog
,CreateNoWindow
илиUseShellExecute
- Неправильная обработка читателей потоков (stream readers)
StandardOutput
илиStandardError
Учитывая вышеприведенное, привожу некоторые базовые указания:
- Используйте события
OutputDataReceived
/ErrorDataRecieved
а НЕStandardOutput
илиStandardOutput
. Это спасет вас от головной боли и ненужного управления потоками.
- Всегда перехватывайте весь вывод И ввод, а если не планируете задавать ввод, то сразу же закройте поток.
- Ваш процесс не закончится до тех пор, пока он не вышел И вы не считали все данные. Событие
OutputDataReceived
МОЖЕТ И БУДЕТ сгенерировано после того как закончился вызов методаWaitForExit()
. Необходимо будет подождать обработчиков для каждого выходного потока и установить дескриптор ожидания (wait handle) как только будет полученоnull
.
Источник тут.