Logo
PREGNANCY
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
 
 
Windows 7

Working in the Background : IMPLEMENTING APPLICATION RESTART AND RECOVERY

4/21/2014 1:46:57 AM

It's now possible to tell Windows that you want your application to automatically restart if it fails. In this case, restart means to start the application over again, not to do anything else. You can also tell Windows to start your application in a recover mode. The recover mode calls a special method in your application to recover any data that the application was working on when it failed.

The restart and recover features are completely independent. There isn't any reason you can't simply implement a recover mode if so desired. The recovery will simply take place when the user restarts the application at some time in the future. Likewise, if your data isn't performing any data manipulation (it might simply be a status indicator), then you can define restart only.

The Code Pack examples show a relatively complex application that implements both restart and recover modes in the \CodePack\Samples\AppRestartRecoveryDemo folder. The example can be a little hard to digest in one big chunk. The example in this section takes just the first step; it demonstrates how to implement a restart feature. After you see how the Application Restart example works, you'll likely want to spend time looking at the Code Pack example to get a better idea of precisely how you could implement both features in your application.

1. Configuring the Application Restart Example

This example begins with a Windows Forms application. You'll need to add a Crash button (btnCrash) to cause the application to crash unexpectedly. Unlike most examples, you'll want to set the btnCrash.Enabled property to false because you can't click Crash immediately after starting the application. In addition, you'll need to add a reference to Microsoft.WindowsAPICodePack.DLL and provide the following using statement:

using Microsoft.WindowsAPICodePack.ApplicationServices;

2. Writing the Application Restart Example Code

The Application Restart example performs a basic task — it crashes. When a user clicks btnCrash, the application simply stops working. At that point, the user sees a somewhat familiar dialog box, the restart dialog box shown in Figure 1. This dialog box is specific to Application Restart, but a number of applications on a Windows 7 system display the same dialog box. When the user clicks Restart, the application restarts. The example application knows it has restarted and displays a dialog box saying so. While all this sounds simple, it wasn't simple at all to implement until Windows 7.

Figure 1. A crashing application can display a restart dialog box like this one.

Windows 7 won't display the restart dialog box for an application that crashes before it has run for 60 seconds. Microsoft hasn't stated why it placed this particular limit on the restart mechanism, but you need to work around it for the example application. To make this task easier, the example displays a countdown timer on btnCrash. You can see the time tick down, and then the code enables the Crash button so you can click it. Listing 1 shows the supporting code to perform this task.

Example 1. Defining the timer
// Define a countdown variable.
private Int32 Countdown;

// Define a timer to use for the countdown.
System.Timers.Timer WaitToCrash;

// A delegate to update the btnCrash.Text property.
private delegate void SetTextCallback(String Value);

// The method called to perform the actual update.
private void SetText(String Value)
{
btnCrash.Text = Value;
}

// A delegate to update the btnCrash.Enabled property.
private delegate void SetEnabledCallback(Boolean Value);

// A method called to enable the button.
private void SetEnabled(Boolean Value)
{
btnCrash.Enabled = Value;
}

// A delegate to disable the counter.
private delegate void SetCounterCallback(Boolean Value);

// A method called to disable the counter.
private void SetCounter(Boolean Value)
{
WaitToCrash.Enabled = Value;
}

void WaitToCrash_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// Check the countdown.
if (Countdown == 0)
{
// Modify the enabled state using a thread-safe method.
SetEnabledCallback Enable = new SetEnabledCallback(SetEnabled);
this.Invoke(Enable, new Object[] { true });

// Modify the caption using a thread-safe method.
SetTextCallback Update = new SetTextCallback(SetText);
this.Invoke(Update, new Object[] { "&Crash" });

// Disable the counter.
SetCounterCallback NoCount = new SetCounterCallback(SetCounter);
this.Invoke(NoCount, new Object[] { false });

// Display a message.
MessageBox.Show("Time to crash the system!");
}


else
{
// Change the countdown value.
Countdown--;

// Modify the text using a thread-safe method.
SetTextCallback Update = new SetTextCallback(SetText);
this.Invoke(Update, new object[] { Countdown.ToString() });
}
}

The code begins by defining an Int32 value, Countdown, which maintains the current countdown value, starting with 60 seconds. The actual timer is a System.Timers.Timer object, WaitToCrash.

The example has to change three properties during the process of displaying the countdown timer. It has to update btnCrash.Text with the latest counter value (so you can see it count down), set btnCrash.Enabled to true when the countdown reaches 0 (so you can click the button), and disable the counter by setting WaitToCrash.Enabled to false. If you try to change any of these values directly, the system will complain. The code creates a delegate and event handler for each property change to handle the changes in a code-safe manner.

The WaitToCrash_Elapsed() event handler processes each WaitToCrash tick event. Normally, the event handler will decrement Countdown and display the new value on btnCrash by invoking its thread-safe SetText() event handler. When Countdown reaches 0, the code enables btnCrash, sets its Text property to &Crash, and disables the counter. The user also sees a message box saying it's time to crash the application.

Now it's time to look at the restart code. The application needs to tell Windows to offer to restart the application when it crashes and place limits on when a restart occurs. In this case, it also requires some method of crashing the application. Listing 2 shows the required code.

Example 2. Restarting an application
public frmMain()
{
// Perform the standard initialization.
InitializeComponent();

// Register the application for restart. We don't want to restart
// the application if it failed as the result of a reboot or a
// patch.
ApplicationRestartRecoveryManager.RegisterForApplicationRestart(
new RestartSettings("/Restart",
RestartRestrictions.NotOnReboot |
RestartRestrictions.NotOnPatch));

// Set the countdown.
Countdown = 60;

// The application can't crash immediately. The system won't restart an
// application that crashes within 60 seconds of starting. Set a timer

// to alert the user to the ability of the system to crash.
WaitToCrash = new System.Timers.Timer(1000);
WaitToCrash.Elapsed +=
new System.Timers.ElapsedEventHandler(WaitToCrash_Elapsed);
WaitToCrash.Enabled = true;

// Display a message when the system has restarted the application,
// rather than starting from scratch.
if (System.Environment.GetCommandLineArgs().Length > 1 &&
System.Environment.GetCommandLineArgs()[1] == "/Restart")
MessageBox.Show("Application is restarted!");
}

private void btnCrash_Click(object sender, EventArgs e)
{
// Cause the application to crash.
Environment.FailFast("Application Restart example has crashed!");
}

The code begins with the form constructor, frmMain(). Registering the application for restart comes first, with a call to ApplicationRestartRecoveryManager.RegisterForApplicationRestart(). Part of registering the application is to tell Windows how and when to restart it. The RestartSettings() constructor accepts two arguments. The first is a string that defines the command line arguments you want passed to the application during a restart. The second is a list of RestartRestrictions enumeration values that defines situations where you don't want the application restarted, such as after a reboot or after someone patches the system.

The next few steps initialize the timer. The code sets Countdown to 60 seconds and configures WaitToCrash. The System.Timers.Timer() accepts an interval in milliseconds — a value of 1,000 configures the timer for one-second intervals.

The last part of frmMain() is potentially the most interesting. Normally, the application won't receive any command line arguments (or, if it does, you'll need to handle them appropriately). Checking for a command line argument with the System.Environment.GetCommandLineArgs().Length property is the first step. When there's a command line argument to process, the application verifies that it's /Restart, which is the command line argument passed as part of the RestartSettings() constructor. When both conditions are satisfied, the application can perform any required restart tasks, such as recovering any data that could have been lost when the application crashed. In this case, the application simply displays a message box.

The btnCrash_Click() event handler sets all the restart events in motion. When the user clicks btnCrash, the code calls Environment.FailFast(), which causes the application to crash. Because the debugger will try to catch and handle this situation, you can't test the application using the debugger. Instead, you must choose Debug => Start Without Debugging or press Ctrl+F5 to start the application.

Other -----------------
- Working in the Background : PROVIDING POWER MANAGEMENT (part 2) - Detecting a Change in Monitor State
- Working in the Background : PROVIDING POWER MANAGEMENT (part 1) - Getting the Power Management State
- Automating Windows 7 Installation : Customizing Images Using Deployment Image Servicing and Management (part 3) - Servicing the Operating System in an Image , Committing an Image
- Automating Windows 7 Installation : Customizing Images Using Deployment Image Servicing and Management (part 2) - Mounting an Image , Servicing Drivers in an Image
- Automating Windows 7 Installation : Customizing Images Using Deployment Image Servicing and Management (part 1) - Viewing Information about an Image with DISM
- Automating Windows 7 Installation : Applying an Image Using ImageX
- Automating Windows 7 Installation : Capturing an Image Using ImageX
- Microsoft Visio 2010 : Creating Web Pages from Visio Drawings (part 4) - Fine-tuning Web Pages and Battling Bugs - Saving a Visio Drawing as a Web Page
- Microsoft Visio 2010 : Creating Web Pages from Visio Drawings (part 3) - Fine-tuning Web Pages and Battling Bugs - Customizing Web Page Output
- Microsoft Visio 2010 : Creating Web Pages from Visio Drawings (part 2) - Exploring Visio-Generated Web Pages
- Microsoft Visio 2010 : Creating Web Pages from Visio Drawings (part 1) - Saving as Web Page
- Microsoft Visio 2010 : Sending Visio Files in Email, Saving as PDF or XPS Files
- Microsoft Visio 2010 : Introducing Data Graphics (part 2) - Creating Data Graphics,Applying Data Graphics to Shapes
- Microsoft Visio 2010 : Introducing Data Graphics (part 1) - What Is a Data Graphic?
- Microsoft Visio 2010 : Linking External Data to Shapes (part 6) - Using Link Data - Linking Data to Shapes Using Link Data
- Microsoft Visio 2010 : Linking External Data to Shapes (part 5) - Using Link Data - Preparing a Master for Link Data , Importing Data for Link Data
- Microsoft Visio 2010 : Linking External Data to Shapes (part 4) - Using the Database Wizard - Taking the Data-Linked Light Bulb Shape for a Spin
- Microsoft Visio 2010 : Linking External Data to Shapes (part 3) - Using the Database Wizard - Setting Up the Excel File as a Data Source
- Microsoft Visio 2010 : Linking External Data to Shapes (part 3) - Using the Database Wizard - Setting Up the Excel File as a Data Source
- Microsoft Visio 2010 : Linking External Data to Shapes (part 2) - Preparing the Light Bulb Shape for Data Linking
 
 
Most view of day
- Accessing and Using Your Network : Working with Offline Files and the Sync Center (part 2) - Synchronizing Offline Files, Handling Synchronization Conflicts
- System Center Configuration Manager 2007 : Customizing Configuration Manager Reports (part 1) - Customizing Report Layout and Display
- Windows Server 2008 : Working with the Schema - Modifying the Schema with adprep, Registering the Active Directory Schema Snap-In
- Windows Phone 8 : Configuring Basic Device Settings - Controlling the Keyboard’s Behavior (part 2) - Clearing Custom Suggestions
- Games and Windows 7 : Games for Windows - LIVE (part 2) - Accessing Games for Windows - LIVE from within Compatible Games
- Microsoft Exchange Server 2013 : Creating new mailboxes (part 2) - Languages
- Windows Phone 8 : Messaging - Composing a New Message (part 4) - Removing a Message Attachment
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Adding Security Encryption to a Workbook
- Windows Phone 8 : Localizing Your Phone Application
- Maintaining Dynamics GP : Validating balances with the Reconcile utility
Top 10
- Configuring and Troubleshooting IPv6 in Windows Vista (part 4) - Troubleshooting IPv6 Connectivity
- Configuring and Troubleshooting IPv6 in Windows Vista (part 3) - Configuring IPv6 in Windows Vista Using Netsh , Other IPv6 Configuration Tasks
- Configuring and Troubleshooting IPv6 in Windows Vista (part 2) - Configuring IPv6 in Windows Vista Using the User Interface
- Configuring and Troubleshooting IPv6 in Windows Vista (part 1) - Displaying IPv6 Address Settings
- Deploying IPv6 : IPv6 Enhancements in Windows Vista
- Games and Windows 7 : Games for Windows - LIVE (part 2) - Accessing Games for Windows - LIVE from within Compatible Games
- Games and Windows 7 : Games for Windows - LIVE (part 1) - Using the Games for Windows - LIVE Marketplace
- Sharepoint 2013 : Client-side Programming - Working with the REST API (part 3)
- Sharepoint 2013 : Client-side Programming - Working with the REST API (part 2) - Working with the REST API in JavaScript
- Sharepoint 2013 : Client-side Programming - Working with the REST API (part 1) - Understanding REST fundamentals
 
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro