none
How to restart an application upon failure using C# RRS feed

  • Question

  • Hi there,
    I am implementing a WinForm application using C# 3.5 on Windows XP. Is there a way to restart the application if it fails?

    I googled around, but seems the Application Recovery and Restart API in C# only works for Vista or Server 2008. I also tried to use Try-Catch in the Main function, but exceptions throw from the Form not catched. Here is the code I tried:


    public static void Main()
     {
         try {
              Application.Run(new MainForm());
         } catch (Exception e)
         { Console.WriteLine("Error occured: " + e.Message);
         }
      }



    class MainForm: Form
    {
        Button clickMe = new Button();
        clickMe.OnClick += new System.EventHandler(clicked);
    }

    private void clicked (object sender, EventArgs e)
    {
        string test= "false";
        Convert.ToInt32(test);
    }

    Then the exception is not raised to the Main function.


    I need the application to be very stable, so it's very important that in case some error happens, it will restart itself. Thanks a lot for any help
    Tuesday, July 7, 2009 6:46 PM

Answers

  • using System;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    
            try
            {
                Application.Run(new Form1());
            }
            catch (Exception ex)
            {
                RestartApplication(ex);
            }
        }
    
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            RestartApplication(e.Exception);
        }
    
        private static void RestartApplication(Exception ex)
        {
            // log exception somewhere, EventLog is one option
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
            Process.Start(Application.ExecutablePath);
            Application.Exit();
        }
    }
    
    • Proposed as answer by OmegaManModerator Tuesday, July 7, 2009 7:49 PM
    • Edited by Tergiver Tuesday, July 7, 2009 7:53 PM a little refactoring
    • Marked as answer by Helen.W Tuesday, July 7, 2009 8:28 PM
    Tuesday, July 7, 2009 7:36 PM

All replies

  • using System;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    
            try
            {
                Application.Run(new Form1());
            }
            catch (Exception ex)
            {
                RestartApplication(ex);
            }
        }
    
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            RestartApplication(e.Exception);
        }
    
        private static void RestartApplication(Exception ex)
        {
            // log exception somewhere, EventLog is one option
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
            Process.Start(Application.ExecutablePath);
            Application.Exit();
        }
    }
    
    • Proposed as answer by OmegaManModerator Tuesday, July 7, 2009 7:49 PM
    • Edited by Tergiver Tuesday, July 7, 2009 7:53 PM a little refactoring
    • Marked as answer by Helen.W Tuesday, July 7, 2009 8:28 PM
    Tuesday, July 7, 2009 7:36 PM
  • It may be that in your example, you haven't told your project you want it to start using your Main Sub. By default, the project's entry point is hidden behind your main form's lifespan. If you want direct control over the entry point, you must set it in the project properties.

    I must warn you of your approach though, as it has happened to me before. One possible case is an infinite loop where initialization of your app would crash it. Then it would keep trying to relaunch itself, crash and overall look very bad in front of your customer.

    Keep that in mind.
    Tuesday, July 7, 2009 7:50 PM
  • Thank a lot! The Appliaction.ThreadException does the trick since I use multiple threads.

    Many thanks!
    Tuesday, July 7, 2009 8:28 PM