11

How can I detect that my .NET application has crashed, and then restart it?

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
  • 1
    I found some solutions to this question (before I asked it), so I thought it would be nice to have the answers in SO. If you have additional answers, please be my guest. Or just vote the best answer to guide others. Also please retag this question as you deem appropriate. – Hosam Aly Feb 08 '09 at 14:43
  • Added info about restarting a console app, as this is apparently what you're using. – HTTP 410 Feb 09 '09 at 09:30

4 Answers4

14

Another solution (based on this example) is to create a launcher that controls the application:

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);
        }
    }
Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
8

If this is a Windows Forms app:

  • Set jitDebugging = true in App.Config. This prevents the built-in Windows Forms unhandled exception handler being triggered.

Now regardless of whether this is a Windows Forms app or a console app:

  • Register for the Application.ThreadException event, e.g. in C#:

    Application.ThreadException += new Threading.ThreadExceptionHandler(CatchFatalException);

At this point, your app is already on its way into a black hole. What happens next depends on whether or not this is a Windows Forms app:

  • If it's a Windows Forms app, call the Application.Restart method in your CatchFatalException event handler.
  • Otherwise you will instead need to p/invoke to the application restart and recovery native functions. That link discusses Vista, but in my tests it works just fine on XP as well.
HTTP 410
  • 17,300
  • 12
  • 76
  • 127
  • Thank you. Is it possible for a console application to do something similar to `Application.ThreadException += MyHandler;`? – Hosam Aly Feb 08 '09 at 21:51
  • Yes, a console app can do the same. – HTTP 410 Feb 08 '09 at 23:17
  • But it does not have access to the Application class, does it? – Hosam Aly Feb 09 '09 at 05:59
  • It does have access to the Application class if you add the correct namespace. But in my test, I see an "Unsupported" exception, so you're right, this doesn't work for Console apps. I will change my answer to reflect this. – HTTP 410 Feb 09 '09 at 09:17
5
  • run the work inside an AppDomain; use the primary AppDomain to monitor it (doesn't guard against process kill, though)
  • lots of exception handling! i.e. don't let a fatal error tear down the process
  • run it in something that already has recycling built in - IIS for example
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    Thanks Marc. Could you please add an example on how to implement the AppDomain-based solution you suggest? – Hosam Aly Feb 08 '09 at 14:46
  • Assuming this is a Windows Forms or console app, you can use Application.Restart - see my answer for details. – HTTP 410 Feb 08 '09 at 23:37
1

A possible solution is to create another process to monitor your application, and restart it if it is terminated:

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

One of the problems with this solution is that it will keep the process restarting forever, until this monitoring application itself is terminated.

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182