Сообщение об ошибках / сбоях из cmd-файлов, работающих под System.Diagnostics.Process - PullRequest
0 голосов
/ 15 сентября 2011

В настоящее время я работаю над системой автоматической установки.Основа того, как это работает, состоит в том, что вещи, которые нужно установить, упакованы вместе с cmd-файлом, который управляет установкой.Если это msi или exe, то cmd-файл сообщит установщику, какие ответы ему нужны, если это sql-скрипт, он запустит его под sqlcmd и т. Д.следующий код C #:

        ProcessStartInfo p = new System.Diagnostics.ProcessStartInfo(filePath + fileToRun);
        p.WorkingDirectory = filePath;
        Process proc = new System.Diagnostics.Process();
        proc.StartInfo = p;

        proc.Start();
        proc.WaitForExit();

И это хорошо работает.Он делает то, что должен.

Однако проблема, с которой я столкнулся, заключается в том, что, поскольку это автоматизировано, а некоторые компоненты зависят от существования предыдущих компонентов, очень важно, чтобы система точно знала, что установленоданная среда, а что нет.Поэтому, если по какой-то причине происходит сбой cmd-файла, мой код C # должен знать об этом.

Я не могу понять, как это сделать.Кажется, что System.Diagnostics.Process изолирует то, что он выполняет, и не имеет представления о том, что происходит внутри процесса, который он выполняет.Ошибка, указывающая на сбой, может быть вызвана многими источниками - это может быть файл cmd, сценарий sql, установщик или powershell.

Так есть ли способ заставить мой код распознавать, когда в процессе произошла ошибка, и записать ее?Я могу изменить файлы cmd, которые запускают код, и попытаться обнаружить ошибки там, но я не могу редактировать файлы, которые пытается запустить cmd.И даже если я могу выделить ошибки в файле cmd, как мне сообщить о них обратно в C #?

Cheers, Matt

1 Ответ

2 голосов
/ 15 сентября 2011

Вы можете перенаправить вывод ошибок процесса и использовать его в своем приложении.

p.UseShellExecute = false; // necessary to redirect stderr
p.RedirectStandardError = true;

тогда

string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();

Или, если у вас есть контроль над ним, вы также можете выбрать несколько значимых кодов выхода для сбоев в вашем процессе, а затем переключить их в своем коде c #. Что-то вроде ...

switch (proc.ExitCode)
{
   case 1 : 
      // component A has failed
      break;
   case 2 : 
      // component B has failed
      break;
   default:
     // unknown error
}
...