Как я могу обнаружить, что мое приложение .NET разбилось, а затем перезапустило его?
Обнаружение и перезапуск моего разбитого приложения .NET
Ответ 1
Другим решением (основанным на данном примере) является создание пусковой установки, которая управляет приложением:
class LauncherProgram
{
static int count = 3;
static void Main()
{
Launch();
Thread.Sleep(Timeout.Infinite);
}
static void Launch()
{
Process process = new Process();
process.StartInfo.FileName = "MyApp.exe";
process.EnableRaisingEvents = true;
process.Exited += LaunchIfCrashed;
}
static void LaunchIfCrashed(object o, EventArgs e)
{
Process process = (Process) o;
if (process.ExitCode != 0)
{
if (count-- > 0) // restart at max count times
Launch();
else
Environment.Exit(process.ExitCode);
}
else
{
Environment.Exit(0);
}
}
Ответ 2
Если это приложение Windows Forms:
- Установите jitDebugging = true в App.Config. Это предотвращает запуск обработчика обработанных обработчиков встроенных форм Windows Forms.
Теперь, независимо от того, является ли это приложением Windows Forms или консольным приложением:
-
Зарегистрируйтесь для события Application.ThreadException, например. в С#:
Application.ThreadException + = новый Threading.ThreadExceptionHandler(CatchFatalException);
На этом этапе ваше приложение уже отправляется в черную дыру. Что будет дальше, зависит от того, является ли это приложением Windows Forms:
- Если это приложение Windows Forms, вызовите метод Application.Restart в обработчике событий CatchFatalException.
- В противном случае вам потребуется p/invoke для перезапуска и восстановления приложений собственных функций. Эта ссылка обсуждает Vista, но в моих тестах она отлично работает и на XP.
Ответ 3
- запустить работу внутри AppDomain; используйте основной AppDomain для его контроля (не защищает от процесса kill, хотя)
- много обработки исключений! то есть не позволяйте фатальной ошибке срывать процесс.
- запустите его в том, что уже имеет встроенную утилиту - например, IIS
Ответ 4
Возможное решение - создать другой процесс для мониторинга вашего приложения и перезапустить его, если он завершен:
class ProcessMonitorProgram
{
const string myProcess = "MyApp.exe";
static void Main()
{
new Timer(CheckProcess, null, 0, 60 * 1000);
Thread.Sleep(Timeout.Infinite);
}
static void CheckProcess(object obj)
{
if (Process.GetProcessesByName(myProcess).Length == 0)
Process.Start(myProcess);
}
}
Одной из проблем с этим решением является то, что он будет поддерживать перезапуск процесса навсегда, пока это приложение мониторинга не будет завершено.