Application Recovery and Restart C# Quick Reference

20 באפריל 2010

אין תגובות

Background


Application Recovery and Restart (ARR) is a feature that allows you to prepare for the impossible (?) case where your application crash or waits forever (“Not Responding”)


The feature lets you “register” for these cases in order to give you the opportunity to save the application data or do some clean up operations, before it ends its life.


This feature exists from Windows Vista, but it seems that not enough people knows it, so let’s see how can anyone use the Windows API Code Pack to easily integrate ARR in their applications.


More information on the feature can be found at Application Recovery and Restart on MSDN.


Step 1 – When to register?


The first step is quite obvious, but needs to be said nevertheless. You should register to ARR when the application loads and unregister when the application unloads.




public MainWindow()
{
    InitializeComponent();
    …
    RegisterApplicationRecoveryAndRestart();
}

 




private void CloseButton_Click(object sender, RoutedEventArgs e)
{
    …
    UnregisterApplicationRecoveryAndRestart();
    App.Current.Shutdown();
}

 


The functions RegisterApplicationRecoveryAndRestart and UnregisterApplicationRecoveryAndRestart are my functions which we will see on the next step.


Step 2 – How to Register?


Before using the ARR feature we check that we’re running on Windows Vista or up by using WindowsAPICodePack CoreHelper.RunningOnVista helper method.




private void RegisterApplicationRecoveryAndRestart()
{
    if (!CoreHelpers.RunningOnVista)
    {
        return;
    }

    // register for Application Restart
    RestartSettings restartSettings =
        new RestartSettings(string.Empty, RestartRestrictions.None);
    ApplicationRestartRecoveryManager.RegisterForApplicationRestart(restartSettings);

    // register for Application Recovery
    RecoverySettings recoverySettings =
        new RecoverySettings(new RecoveryData(PerformRecovery, null), KeepAliveInterval);
    ApplicationRestartRecoveryManager.RegisterForApplicationRecovery(recoverySettings);
}

Register for restart


Then we do two things. First we register for restart. The Windows Error Reporting component will present the user the restart dialog if the application had an unhandled exception or has been unresponsive for more than 60 seconds.


When registering for restart we supply an instance of RestartSettings. The first parameter it gets is the command line arguments that will be used for the restart, in case we want to define some special parameters (like “run in safe mode”).
The second parameters is an enum that allows us to restrict the restart in some cases, for example, we can set RestartRestriction.NotOnReboot if we don’t want our application to restart if the computer was restarted due to a system update.


Available restrictions are:






















Restriction


Meaning

None No restart restrictions
NotOnCrash

Do not restart the process if it terminates due to an unhandled exception.

NotOnHang

Do not restart the process if it terminates due to the application not responding.

NotOnPatch

Do not restart the process if it terminates due to the installation of an update.

NotOnReboot

Do not restart the process if the computer is restarted as the result of an update.


Register for recovery


The second thing we do is register for recovery. This means that if the application will need a restart (from the same reasons as before), what function do we want to run to allow later recovery.


When registering for recovery we supply an instance of RecoverySettings. The first parameter it gets is the RecoveryData object, which wraps a delegate to be called and some state parameter that will be passed (in this example, null). The second parameter is the keep alive interval, which will be explained shortly.


Implementing the recovery function


The recovery function should obey some rules in order to avoid the application getting stuck (again) in the recovery function. You must call ApplicationRestartRecoveryManager.ApplicationRecoveryInProgress every few (mili)seconds (in the example, KeepAliveInterval = 5000). This tells the ARR mechanism, “I know it takes some time, but don’t worry, I’m still alive and working on the recovery stuff”.


Also, at the end of the recovery function you must call ApplicationRestartRecoveryManager.ApplicationRecoveryFinished with a parameter that indicates whether you succeeded in doing the recovery.




/// <summary>
/// Performs recovery by saving the state
/// </summary>
/// <param name="parameter">Unused.</param>
/// <returns>Unused.</returns>
private int PerformRecovery(object parameter)
{
    try
    {
        ApplicationRestartRecoveryManager.ApplicationRecoveryInProgress();
        
        // Save your work here for recovery
        …

        ApplicationRestartRecoveryManager.ApplicationRecoveryFinished(true);
    }
    catch
    {
        ApplicationRestartRecoveryManager.ApplicationRecoveryFinished(false);
    }

    return 0;
}

Step 3 – How to unregister




private void UnregisterApplicationRecoveryAndRestart()
{
    if (!CoreHelpers.RunningOnVista)
    {
        return;
    }

    ApplicationRestartRecoveryManager.UnregisterApplicationRestart();
    ApplicationRestartRecoveryManager.UnregisterApplicationRecovery();
}

This is just some cleanup code to properly unregister from Application Recovery and Restart.


That’s it for now,
Arik Poznanski.

kick it on DotNetKicks.com Shout it

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים