Windows Restart and Recovery Recipe

Vista introduced two closely related features: Application Restart and Application Recovery. These features are designed to eliminate much of the pain caused by the unexpected termination of your application, whether as a result of an unhandled exception, a “hard hang,” or any other crash.

Application Recovery applies to applications that have a “document” or any other in-memory information that might be lost when the application closes unexpectedly. Application Restart applies to all applications, whether they might have unsaved data or not, and to more unexpected closes, including a DLL update or a system reboot. Today, a large number of applications such as Windows Office (Microsoft Word and friends) use these features. Even if something does go wrong (and when it comes to software, it is most likely that at some point something will go wrong), the application together with the operating system can provide a seamless recovery path that makes the user feel a little less frustrated.

Basically, any Windows application can register with the operating system for restart and, optionally, for recovery.


  • To register for restart, the application provides a command line argument that will inform the application it is restarting. A restarted application that uses recovery can look in the known location for recovery data when it is restarted, and reload the unsaved data.
  • To register for recovery, the application provides a callback function. The operating system will call this function on a separate thread (remember, your main thread just threw an exception) if the application crashes or hangs. The callback function can save any unsaved data in a known location. It cannot access the UI thread, which is no longer running. Do note that the call back function can’t run forever. The operating system will not permit it to run more than few seconds.
All this sounds great; what is the problem?

The native Win32 API calls to register for restart and for recovery are fairly simple to use. The Windows API Code Pack includes a managed wrapper for the both recovery and restart functionality.

However, the problem most developers experience is the degree of freedom allowed regarding the recovery method. Since the API requires a callback that the operating system calls when something bad happens to your application, developers can write out their unsaved data in any way they choose, and anywhere.

While writing a file to the hard drive is an obvious choice, some might decide to add records to a database, upload a file to a network location, send an email message, print something, add an event to the event log, and so on. Since the application is in an unknown state during the recovery callback, these are actually poor choices. If you are looking to implement the recovery callback, you should choose a solution that is fast (quick code execution), and that relies on the bare minimum of available resources. Therefore writing to the hard drive is probably your best choice.

Once the decision is made to write a file to the hard drive, more questions arise. What folder should be used? Many developers use “the current directory” – which works great during development, but once the application is deployed and installed under Program Files (for example), the Windows UAC will prevent your application from writing to that folder through yet another exception on your recovery callback method… “The AppData (%AppData%) folder for the user is a much better choice.” – Not the ideal situation.

But there are yet more questions; for example, what file format should be used? What should the file be named? How can the restarting application find the file if the filename is not hardcoded to be the same every time? What will happen if two instances, with different data, require restart at the same time – how will they each save their own data separately and find their own data on restart? Fortunately, we have a recipe for developers who need to cook this into their code.

The Windows Restart and Recovery Recipe includes a library that solves all of the above mentioned problems for both managed (.NET) and native (C++) implementations. The recipe includes code samples that show how to use the library, and documentation explaining in detail how the library works.

Our goal was to make using the Restart and Recovery features super easy and accessible.

For example: The recipe is provided as a .NET assembly - WindowsRecipes.RestartManager. Projects that use the recipe must add a reference to the assembly. There is one class - RestartRecoveryHelper, with two methods, CheckForRestart and RegisterForRestartAndRecovery. Next, you’ll need to point to your data model class; any class that is serializable, using the Serializable attribute, can be used as data to be saved. Then all you need to do is simply call the RegisterForRestartAndRecovery method like the following snippet.

doc = new SampleDocument(); // initialize doc as required rrh = new WindowsRecipes.RestartManager.RestartRecoveryHelper(); SampleDocument recovereddoc = rrh.CheckForRestart(); if (recovereddoc != null) { doc = recovereddoc; //use contents of doc to set values of controls on the form } rrh.RegisterForRestartAndRecovery("TestHarness",doc,WindowsRecipes.RestartManager.FileType.Xml);
This code includes registering to the recovery method as well as recovering from previous unexpected application terminations.

The SampleDocument is a serializable class we use just for demo purposes. Next we create the helper class – RestartRecoveryHelper, that can handle the specific SampleDocument class type. You can create any number of such files for any data object that you want to save, or you can create one big nested data object. Both are valid, as long as the object is serializable.

Next we check to see if the application was restarted due to an unexpected termination. If so, we then retrieve the data that was saved before the application terminated and use it in our application logic. For example, we can use the recovered data to set values on a few controls. This completes the recovery part.

Now we want to register the app to restart and recovery in case it crashes again. Simply call the RegisterForRestartAndRecovery method by passing a string as the name of the app, the doc as the data object to save, and the file type to save.

The recipe takes care of everything for you. The temporary recovery files are saved in the Roaming Application Data folder usually located at “C:\Users\\AppData\Roaming”. The file names are guaranteed to be unique, the format is up to you, binary or XML. This way, we can make sure that a given application can handle multiple users and multiple crashes. Once recovered, the files are removed.

Here is a short video by Kate Gregory, explaining this in great detail. You can also watch a video showing the native APIs.



If you are interested, you can read more about this in the Windows Restart and Recovery Recipe and download the code and documentation.




aggbug.aspx
More...
 
Back
Top