2009-02-08 3 views
11

Как я могу обнаружить, что мое приложение .NET разбилось, а затем перезапустило его?Обнаружение и перезагрузка моего разбитого .NET-приложения

+0

Я нашел некоторые решения по этому вопросу (прежде чем я его попросил), поэтому я подумал, что было бы неплохо иметь ответы в SO. Если у вас есть дополнительные ответы, пожалуйста, будьте моим гостем. Или просто проголосовать за лучший ответ, чтобы вести других. Также, пожалуйста, повторите этот вопрос, как вы сочтете нужным. –

+0

Добавлена ​​информация о перезапуске консольного приложения, поскольку это, по-видимому, то, что вы используете. – RoadWarrior

ответ

14

Другое решение (на основе this example) заключается в создании ракеты-носителя, который контролирует применение:

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); 
     } 
    } 
+1

Единственное возможное обновление - сделать «сторожевой таймер» службой Windows. –

+0

лучше добавить некоторый код временной метки и обнаружить, что приложение разбилось при запуске – Sean

1

Возможное решение создать еще один процесс для контроля приложения и перезапустите его, если он завершается:

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); 
    } 
} 

Одна из проблем, с этого решения заключается в том, что он будет держать процесс перезагрузки навсегда, пока это приложение мониторинга прекращается.

5
  • запустить работу внутри AppDomain; используйте основной AppDomain для его контроля (не защищает от процесса kill, хотя)
  • много обработки исключений! т.е. не позволяйте фатальная ошибка срывать процесс
  • запустить его в чем-то, что уже имеет рециркуляцию встроенный в - IIS, например
+1

Спасибо Marc. Не могли бы вы добавить пример того, как реализовать решение на базе AppDomain, которое вы предлагаете? –

+0

Предполагая, что это приложение Windows Forms или консольное приложение, вы можете использовать Application.Restart - см. Мой ответ для деталей. – RoadWarrior

8

Если это приложение Windows Forms:

  • Set jitDebugging = true в App.Config. Это предотвращает запуск обработчика обработанных обработчиков встроенных форм Windows Forms.

Теперь независимо от того, является ли это Windows, приложение или консольного приложения Forms:

  • Регистрация для Application.ThreadException события, например, в C#:

    Application.ThreadException + = новое Threading.ThreadExceptionHandler (CatchFatalException);

На данный момент ваше приложение уже на пути в черную дыру. Что произойдет дальше, зависит от того, или нет, это приложение Windows Forms:

  • Если это приложение под управлением Windows Forms, вызовите метод Application.Restart в обработчике событий CatchFatalException.
  • В противном случае вам потребуется p/invoke для собственных функций application restart and recovery. Эта ссылка обсуждает Vista, но в моих тестах она отлично работает и на XP.
+0

Спасибо. Возможно ли консольное приложение сделать что-то похожее на «Application.ThreadException + = MyHandler;»? –

+0

Да, консольное приложение может сделать то же самое. – RoadWarrior

+0

Но у него нет доступа к классу Application, не так ли? –

Смежные вопросы