Обнаружение и перезапуск моего разбитого приложения .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);
    }
}

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