Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C#
Article

Vista Application Crash Recovery in C#

Rate me:
Please Sign up or sign in to vote.
4.79/5 (18 votes)
4 Mar 20072 min read 87.2K   1.2K   55   19
A demonstration class for adding Application Recovery to your Windows Vista C# application.

Sample Image - VistaApplicationRecovery.jpg

Introduction

Using the new Vista API, your application can now attempt to recover from a crash.

Background

A new feature available in Vista is the ability to have a callback when your application crashes. This can allow you to attempt to persist your applications data before it is terminated. Upon restart, you can then reload that persisted data, thus giving your user a better experience (of course, it shouldn't crash in the first place, but we're being realistic, right!).

Using the code

I've created a class called ApplicationRecovery. You can use this in your own applications to be notified when there is a crash and attempt to persist the data.

The main areas you should make note of are:

  • The Main() function in Program.cs needs modifying:

    C#
    static void Main()
    {
      //Turn off global exception handling.
      Application.SetUnhandledExceptionMode(
         UnhandledExceptionMode.ThrowException);
    
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
    
      using (Form1 form = new Form1())
      {
        //Add the event handler
        ApplicationRecovery.OnApplicationCrash +=
            new ApplicationRecovery.ApplicationCrashHandler(
                form.ApplicationRecovery_OnApplicationCrash);
    
        //Let Windows Vista know that your
        //application wants notification when it crashes.
        ApplicationRecovery.RegisterForRestart();
    
        Application.Run(form);
      }
    }

  • In the Form1() constructor (or another appropriate place) you need to check if there is recovery data that the application should attempt to load.

    C#
    public Form1()
    {
      InitializeComponent();
    
      //Check to see if the recovery file exists.
      //If it does, attempt to recover the data.
      if (System.IO.File.Exists(Application.UserAppDataPath +
        @"\" + RECOVERY_FILENAME))
      {
        if (RecoverData())
        {
          //Change the form title
          this.Text += "- Recovered";
        }
        else
        {
          //Change the form title
          this.Text += "- Could not recover";
        }
      }
    
      tmrCrashCountdown.Start();
    }

  • In the sample application there is a timer tmrCrashCountdown which prevents the user from crashing the application before 60 seconds. The application needs to be running for at least 60 seconds before Windows will attempt to recover and restart. This is so that you don't get an application continually crashing and restarting.

  • Finally, you need to implement the handler for the ApplicationRecovery.OnApplicationCrash event and the RecoverData() method. This is referenced in the Main() function.

    C#
    public void ApplicationRecovery_OnApplicationCrash()
    {
      try
      {
        //Save the data to recover to a text file.
        //You may use any method you deem fit.
        System.IO.File.WriteAllText(Application.UserAppDataPath +
            @"\" + RECOVERY_FILENAME, DataToRecover);
    
        //Let the application recovery know that you
        //finished successfully.
        ApplicationRecovery.ApplicationRecoveryFinished(true);
      }
      catch
      {
        //Or let it know that recovery failed.
        ApplicationRecovery.ApplicationRecoveryFinished(false);
      }
    }
    
    private bool RecoverData()
    {
      bool result;
    
      try
      {
        txtData.Text = System.IO.File.ReadAllText(
            Application.UserAppDataPath + @"\" + RECOVERY_FILENAME);
        System.IO.File.Delete(Application.UserAppDataPath +
            @"\" + RECOVERY_FILENAME);
        result = true;
      }
      catch
      {
        result = false;
      }
    
      return result;
    }

Our application saves the data to a text file, and reloads it on restart. You can implement any method you prefer to persist your data.

A quick look at the ApplicationRecovery class

The ApplicationRecovery class imports the following four functions from the new Vista API:

  • RegisterApplicationRestart
  • RegisterApplicationRecoveryCallback
  • ApplicationRecoveryInProgress
  • ApplicationRecoveryFinished

RegisterApplicationRestart notifies windows that we would like the application to be automatically restarted in the event of a crash.

The RegisterApplicationRecoveryCallback function is the one which is called by Vista when it notifies your application that it is going to be shutdown.
The callback function itself calls our function HandleApplicationCrash which raises our OnApplicationCrash event.

If the user clicks cancel whilst waiting for us to recover, we get notified by the output parameter of ApplicationRecoveryInProgress (which we check every second thanks to a timer in our callback function). When we have finished, we let Windows know by using the ApplicationRecoveryFinished passing either true of false (depending upon our success at recovery).

Points of Interest

The method for debugging the recovery code is worth noting.

  1. Remember to run the application outside of the Visual Studio debugger (Start Without Debugging).
  2. When it crashes, and before you click on either the "Send To Microsoft" or "Cancel" button in the Error Reporting dialog you should use Debug > Attach To Process and attach to your process. Your code will now jump into callback function (HandleApplicationCrash).

History

  • 4th March 07 - Modified ResgtartFlags enum definitions in source code to match updated MSDN documentation (thanks georg)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) Entity Group Ltd
United Kingdom United Kingdom
Chris Buckett is developer based in Maidstone, Kent, UK. He has been producing beskpoke software solutions in the accounting and technology fields since 1995, initially using Borland Delphi, and in the past few years using Microsoft C#, VB.Net, ASP.NET, Winforms, Sql Server and related technologies.
Chris Buckett is married with 2 children, and enjoys hiking, photography and playing the melodeon (although rarely all at the same time).

Comments and Discussions

 
QuestionDoes this works for os later then vista like windows 8 or 10 Pin
Member 1361394022-Aug-18 22:55
Member 1361394022-Aug-18 22:55 
GeneralVB Version Pin
User 451897312-Nov-07 11:39
User 451897312-Nov-07 11:39 
GeneralRe: VB Version Pin
Chris Buckett12-Nov-07 21:32
Chris Buckett12-Nov-07 21:32 
GeneralVery helpful Pin
Mariah L10-Jun-07 23:49
Mariah L10-Jun-07 23:49 
GeneralExcellent Pin
Patrick Klug17-Apr-07 19:23
Patrick Klug17-Apr-07 19:23 
GeneralVery helpful Pin
Tom Clement14-Mar-07 19:41
professionalTom Clement14-Mar-07 19:41 
GeneralI don't understand... Pin
candlelight998-Mar-07 11:56
candlelight998-Mar-07 11:56 
GeneralRe: I don't understand... Pin
Chris Buckett8-Mar-07 21:16
Chris Buckett8-Mar-07 21:16 
GeneralRe: I don't understand... Pin
candlelight999-Mar-07 0:47
candlelight999-Mar-07 0:47 
GeneralRe: I don't understand... Pin
Chris Buckett9-Mar-07 0:51
Chris Buckett9-Mar-07 0:51 
JokeBut...Vista never crashes.... Pin
ednrgc7-Mar-07 2:50
ednrgc7-Mar-07 2:50 
GeneralRe: But...Vista never crashes.... Pin
Chris Buckett7-Mar-07 11:00
Chris Buckett7-Mar-07 11:00 
GeneralSounds good... but Pin
Alexander German5-Mar-07 10:14
Alexander German5-Mar-07 10:14 
GeneralRe: Sounds good... but Pin
SpaceQ5-Mar-07 22:40
SpaceQ5-Mar-07 22:40 
GeneralRe: Sounds good... but Pin
Necromantici17-Jul-08 8:47
Necromantici17-Jul-08 8:47 
GeneralWrong constants Pin
georgwaechter4-Mar-07 6:20
georgwaechter4-Mar-07 6:20 
GeneralRe: Wrong constants Pin
Chris Buckett4-Mar-07 8:41
Chris Buckett4-Mar-07 8:41 
GeneralGood Job! Pin
UnRusoDeCaracas14-Feb-07 18:26
UnRusoDeCaracas14-Feb-07 18:26 
GeneralRe: Good Job! Pin
Dr.Luiji18-Feb-07 10:58
professionalDr.Luiji18-Feb-07 10:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.