T-20: Die Restart-And-Recovery-API

Gastposting von Oliver Scheer , Developer Evangelist - Windows, Silverlight und UI-Technologien bei der Microsoft Deutschland GmbH.

20_0Nur noch 20 Tage bis zum Windows 7 Launch.

Meine Programme stürzen nicht ab! Nein ganz bestimmt nicht! Versprochen! Großes Indianer-Ehrenwort!

Aber falls es doch mal passiert, dass eine Anwendung „abstürzt“, bzw. einfach nicht das tut, was man von ihr erwartet, dann kann man das jetzt stilvoll und mit einem automatischen Neustart der Anwendung geschehen lassen. Hierbei hilft die Restart-And-Recovery-API, die bereits in Windows Vista eingeführt und nun in Windows 7 erweitert wurde.

Jeder von uns war bestimmt schon einmal in der Situation, dass er lange an einem Dokument gearbeitet hat bis die Anwendung plötzlich einfach abgestürzt ist. Die Anwendung reagiert einfach nicht mehr und alle Daten sind verloren. Vielleicht haben sie es auch schon einmal gesehen, dass einige Anwendungen nach einem Absturz anbieten, direkt wieder neu zu starten. Und im Startvorgang werden dann die verloren geglaubten Daten wiederhergestellt. Benutzer solcher Anwendungen können sich glücklich schätzen.

clip_image002

Die Anwendung läuft noch ….

clip_image004

Ups, die Anwendung funktioniert nicht mehr.

clip_image006

Und startet sich von selbst neu.

clip_image008

Eine quasi sich selbst regenerierende Anwendung kann jeder mit Hilfe der Restart-And-Recovery-API erstellen. Es sind nur wenige Schritte dazu notwendig:

Schritt 1: Registrieren der Anwendung für einen Restart

private void RegisterForRestart()
{
ApplicationRestartRecoveryManager.RegisterForApplicationRestart(
new RestartSettings("/restart",
RestartRestrictions.NotOnReboot | RestartRestrictions.NotOnPatch));
}

Schritt 2: Registrieren der Anwendung für die Wiederherstellung von Daten

private void RegisterForRecovery()
{
RecoveryData data = new RecoveryData(new RecoveryCallback(RecoveryProcedure), null);
RecoverySettings settings = new RecoverySettings(data, 0);
ApplicationRestartRecoveryManager.RegisterForApplicationRecovery(settings);
}

Schritt 3: Implementieren der Recovery-Methode

private int RecoveryProcedure(object state)
{

PingSystem();

File.WriteAllText(RecoveryFile, string.Format("{1}{0}{2}{0}{3}", DataSeparatorString, CurrentFile.Filename, CurrentFile.IsDirty, CurrentFile.Contents));

Debug.WriteLine("File path: " + RecoveryFile);
Debug.WriteLine("File exists: " + File.Exists(RecoveryFile));
Debug.WriteLine("Application shutting down…");

ApplicationRestartRecoveryManager.ApplicationRecoveryFinished(true);
return 0;
}

Schritt 4: Prüfen, ob der Benutzer den Restart abgebrochen hat

private void PingSystem()
{
// Find out if the user canceled recovery.
bool isCanceled = ApplicationRestartRecoveryManager.ApplicationRecoveryInProgress();

if (isCanceled)
{
Console.WriteLine("Recovery has been canceled by user.");
Environment.Exit(2);
}

}

Schritt 5: Daten beim Neustart wiederherstellen

private void RecoverLastSession(string command)
{
if (!File.Exists(RecoveryFile))
{
MessageBox.Show(this, string.Format("Recovery file {0} does not exist", RecoveryFile));
internalLoad = true;
textBox1.Text = "Could not recover the data. Recovery data file does not exist";
internalLoad = false;
UpdateAppTitle();
return;
}

// Perform application state restoration actions here.
string contents = File.ReadAllText(RecoveryFile);
CurrentFile.Filename = contents.Remove(contents.IndexOf(Form1.DataSeparatorString));
contents = contents.Remove(0, contents.IndexOf(Form1.DataSeparatorString) +
Form1.DataSeparatorString.Length);
CurrentFile.IsDirty = contents.Remove(contents.IndexOf(Form1.DataSeparatorString)) == "True" ? true : false;
contents = contents.Remove(0, contents.IndexOf(Form1.DataSeparatorString) + Form1.DataSeparatorString.Length);
CurrentFile.Contents = contents;

// Load our textbox
textBox1.Text = CurrentFile.Contents;

// Update the title
UpdateAppTitle();

// Reset our variable so next title updates we don’t show the "recovered" text
recovered = false;
}

Schritt 0: Die eigentliche Anwendung

public Form1()
{
Debug.WriteLine("ARR: Demo started");
InitializeComponent();
UpdateAppTitle();
RegisterForRestart();
RegisterForRecovery();

if (System.Environment.GetCommandLineArgs().Length > 1 && System.Environment.GetCommandLineArgs()[1] == "/restart")
{
RecoverLastSession(System.Environment.GetCommandLineArgs()[1]);
}
}

Das vollständige Codebeispiel befindet sich im Windows API Code Pack.

Video des Tages

Get Microsoft Silverlight