Click here to Skip to main content
Click here to Skip to main content

Vista Application Crash Recovery in C#

, 4 Mar 2007
Rate this:
Please Sign up or sign in to vote.
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:

    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.

    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.

    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

Share

About the Author

Chris Buckett
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).
Follow on   Twitter

Comments and Discussions

 
GeneralVB Version PinmemberAmrykid12-Nov-07 11:39 
do u have a vb version also?
 
_____________________________
Don't download it, make it.
Visual Basic /C#

GeneralRe: VB Version PinmemberChris Buckett12-Nov-07 21:32 
GeneralVery helpful PinmemberMariah L10-Jun-07 23:49 
GeneralExcellent PinmemberPakl17-Apr-07 19:23 
GeneralVery helpful PinmemberTom Clement14-Mar-07 19:41 
GeneralI don't understand... Pinmembercandlelight998-Mar-07 11:56 
GeneralRe: I don't understand... PinmemberChris Buckett8-Mar-07 21:16 
GeneralRe: I don't understand... Pinmembercandlelight999-Mar-07 0:47 
GeneralRe: I don't understand... PinmemberChris Buckett9-Mar-07 0:51 
JokeBut...Vista never crashes.... Pinmemberednrgc7-Mar-07 2:50 
GeneralRe: But...Vista never crashes.... PinmemberChris Buckett7-Mar-07 11:00 
GeneralSounds good... but PinmemberAlexander German5-Mar-07 10:14 
GeneralRe: Sounds good... but PinmemberSpaceQ5-Mar-07 22:40 
GeneralRe: Sounds good... but PinmemberNecromantici17-Jul-08 8:47 
GeneralWrong constants PinmemberGeorgWaechter4-Mar-07 6:20 
GeneralRe: Wrong constants PinmemberChris Buckett4-Mar-07 8:41 
GeneralGood Job! PinmemberUnRusoDeCaracas14-Feb-07 18:26 
GeneralRe: Good Job! PinmemberDr.Luiji18-Feb-07 10:58 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 4 Mar 2007
Article Copyright 2007 by Chris Buckett
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid