Les nouvelles API de Windows Vista et Windows Serveur 2008 :

API Application Recovery & Restart

Auteur : Eric Vernié, responsable technique en charge des relations développeurs


Document de référence

Révision 1.0

 


Table des matière

Introduction Introduction
Application recovery and restart Application recovery and restart
S'enregistrer pour le redémarrage S'enregistrer pour le redémarrage
Récupération des données saisies Récupération des données saisies
Application de test Application de test
Quelques mots sur le code fournis : Quelques mots sur le code fournis :
Conclusion Conclusion

 

Introduction

A la sortie de Windows Vista on vous a beaucoup parlé de l'expérience utilisateur, au travers de sa nouvelle interface graphique, au travers de la sécurité, ainsi qu'au travers de la version 3.0 du Framework .NET. Pléthore d'articles sur la possibilité de développer de nouvelles applications qui prennent en charge la 3D avec les API Windows Presentation Fundation (WPF), qui communique à l'aide de Windows Communication Fundation (WCF), ainsi que Windows Workflow Fundation (WF).

Mais ce n'est que la partie émergée de l'iceberg. En effet Windows Vista et Windows Serveur 2008 vont bien au delà, et apportent de grandes nouveautés, tant au niveau noyau (que je traiterai dans un autre article), qu'au niveau API Win32 et COM et qui ne sont pas exposées directement par le Framework .NET.

Ces nouveautés, mettent en évidence 3 piliers fondamentaux de Windows Vista et de Windows Serveur 2008 :

  • La robustesse
  • La performance
  • La sécurité

Dans la série d'articles qui vont suivre, je me propose d'ouvrir un peu le capot et de vous exposer ces nouvelles API afin d'illustrer code à l'appuie, ces 3 piliers.

Il est clair que nous ne pourrons pas explorer les 7000 nouvelles APIs, nous nous concentrerons donc sur ce que la documentation MSDN nous indique en tant que nouveautés :
(ms-help://MS.MSSDK.1033/MS.WinSDK.1033/winprog/winprog/windows_vista.htm)

  • Application Recovery and Restart
  • Boot Configuration Data
  • Common Log File System
  • Condition Variables
  • Debug Help Library 6.6
  • Kernel Transaction Manager (KTM)
  • Multimedia Class Scheduler Service
  • Object Namespaces
  • One-Time Initialization
  • Performance Logs and Alerts
  • Restart Manager
  • Thread Ordering Service
  • Thread Pool
  • Transactional NTFS (TxF)
  • Wait Chain Traversal
  • Windows Error Reporting

Technologies utilisées:

C/C++

C++/CLI (C++ qui cible la plate-forme .NET)

Visual Studio 2008 Beta 2

(Disponible en téléchargement ici : https://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx)

Software development Kit Vista: https://www.microsoft.com/downloads/details.aspx?familyid=FF6467E6-5BBA-4BF5-B562-9199BE864D29&mg_id=10114

Si vous n'avez pas installé Visual Studio 2008 Beta2, il vous faut le framework .NET 3.5 https://www.microsoft.com/downloads/details.aspx?FamilyID=1343d537-a62f-4a6e-9727-7791bf4cc2bd

Haut de pageHaut de page

 

Application recovery and Restart

Ce jeu d'API est en corrélation directe avec le jeu d'API Windows Error Reporting (WER) que nous évoquerons plus en détails dans notre prochain article. Pour bien comprendre ce qu'est WER un petit mot s'impose.
WER est une fonctionnalité de Windows qui permet à l'utilisateur de notifier Microsoft via le site http://winqual.microsoft.com des erreurs de l'application, des erreurs du noyau etc. Microsoft, est en mesure alors d'utiliser cette fonctionnalité pour fournir des solutions à l'utilisateur. Les développeurs peuvent utiliser cette infrastructure et recevoir des informations afin d'améliorer leurs applications.

WER est désormais personnalisable afin que le développeur puisse ajouter des informations au rapport envoyé à Microsoft.

Figure 1, illustre Windows Error Reporting lorsque l'application TestRM.EXE plante.

Figure 1 : Interface typique de Windows Error Reporting dans Windows Vista
Figure 1 : Interface typique de Windows Error Reporting dans Windows Vista

Quel développeur n'a jamais implémenté un système, qui permet à l'application de redémarrer si jamais une erreur fatale survient ? Qui n'a jamais essayé d'implémenter un système robuste, qui permet de récupérer des données saisies par l'utilisateur après un plantage de l'application ? (Windows Word en est une illustration, ou après plantage il vous demande si vous souhaitez récupérer le document)

La bonne nouvelle, c'est qu'avec Windows Vista et Windows Serveur 2008 ces deux fonctionnalités sont proposées en standard. En effet, comme son nom l'indique, ce jeu d'API, permet de redémarrer l'application si une erreur fatale survient, mais plus encore, permet d'exécuter une méthode de rappel après une erreur fatale, et ceci afin de pouvoir sauvegarder et récupérer les données saisies.

Alors comment ça marche ?

Haut de pageHaut de page

S'enregistrer pour le redémarrage

Tout d'abord il faut enregistrer son application auprès de Windows Error Reporting afin qu'il puisse la redémarrer.

Pour ce faire, vous devez utiliser l'API

RegisterApplicationRestart(PCWSTR pwzCommandline, DWORD dwFlags)

La premier fois que l'on appel cette API, le 1er paramètrepwzCommandline, peut être nulle, par contre il nous servira lors d'un second appel car nous lui passerons un fichier qui contient les données à récupérer. Le second paramètre dwFlagsindique comment se comporter lorsque l'application plante. Dans notre exemple nous passerons 0, mais voici les différentes valeurs possibles :

Valeur Signification
RESTART_NO_CRASH
1
Ne pas redémarrer le processus, si il c'est terminé du à une exception non gérée
RESTART_NO_HANG
2
Ne pas redémarrer le processus s'il ne répond pas
RESTART_NO_PATCH
4
Ne pas redémarrer le processus s'il c'est terminé du à l'installation de mise à jour
RESTART_NO_REBOOT
8
Ne pas redémarrer le processus si l'ordinateur a redémarré du à une mise à jour.

Exemple :

HRESULT hr=S_OK;//Enregistre l'application courante      hr=::RegisterApplicationRestart (L"",0);      if (FAILED(hr))
      {           //Code omis pour plus de clarté      }

Une fois que l'application est enregistrée pour redémarrage, si une erreur fatale survient, Window Error Reporting vous propose de redémarrer l'application (Figure 2)

Figure 2 : redémarrage de l'application
Figure 2 : redémarrage de l'application

Remarque :

Pour que le redémarrage de l'application soit pris en compte, il faut attendre au moins 60 Secondes.

Il est possible de se dés enregistrer grâce à l'API UnregisterApplicationRestart(void).

Pour en savoir plus : https://msdn2.microsoft.com/en-us/library/aa373347.aspx

Si cette API est intéressante pour l'utilisateur, car il n'a pas à relancer l'application lui-même, son expérience sera meilleur, si-il n'a pas à saisir à nouveau la totalité des données qu'il aurait saisi. Imaginez sa joie, lorsqu'au redémarrage de l'application les données sont toujours là !!!!

C'est ce que nous allons découvrir dans le chapitre suivant.

Haut de pageHaut de page

Récupération des données saisies

Pour pouvoir récupérer les données, il va falloir enregistrer auprès de Windows Error Reporting, une méthode de rappel (qui devra faire le travail de récupération), et qui sera appelée par le système lors du plantage de l'application.

L'API à utiliser est :

RegisterApplicationRecoveryCallback( APPLICATION_RECOVERY_CALLBACK pRecoveryCallback,

  PVOID pvParameter,

  DWORD dwPingInterval,

  DWORD dwFlags

);

  • Le premier paramètre et le plus important, est un pointeur sur une méthode qui doit avoir la signature suivante : DWORD WINAPI ApplicationRecoveryCallback(PVOID pvParameter)
    C'est cette méthode qui devra faire le travail de récupération, comme nous le verrons plus loin
  • Le second qui peut être nulle est un pointeur sur des données que l'on souhaiterait passer à la fonction de rappel.
  • Le troisième, constitue l'intervalle de temps pour la récupération des données. Cet intervalle est important, car en accord avec l'API ApplicationRecoveryInProgress il permet à l'utilisateur d'arrêter la récupération à n'importe quel moment.
  • Le dernier n'est pas utilisé

Exemple :

Pour en savoir plus : https://msdn2.microsoft.com/en-us/library/aa373347.aspx

      HRESULT hr=S_OK;            hr = ::RegisterApplicationRecoveryCallback((APPLICATION_RECOVERY_CALLBACK)Recover,NULL,
                                              RECOVERY_DEFAULT_PING_INTERVAL,                                          0);        if (FAILED(hr))       {       }

//Méthode de rappelDWORD WINAPI Recover(PVOID pContext){    BOOL bCanceled = FALSE;    // Sauvegarde des informations..
    // Il est important d'appeler la fonction ApplicationRecoveryInProgress dans l'intervalle de temps spécifié, sinon la méthode de rappel s'arrête
    ApplicationRecoveryInProgress(&bCanceled);    if (bCanceled)      {          wprintf(L"Recovery was canceled by the
user.\n");              goto cleanup;    }cleanup:         //Il est important de signaler que c'est fini.
       ApplicationRecoveryFinished((bCanceled) ? FALSE: TRUE);    return 0;}

Pour en savoir plus : https://msdn2.microsoft.com/en-us/library/aa373347.aspx

Haut de pageHaut de page

Application de test

Avec cet article, vous retrouverez, un exemple qui met en œuvre ces API.
Mais attention, il ne fonctionne que sous Windows Vista ou Windows Serveur 2008, car ces API ne sont pas disponibles avec les versions antérieures de Windows.

  1. Démarrez l'application TestRM.EXE
  2. Saisissez des données dans le formulaire, vous pouvez même ajoutez une image
    Démonstration Application Recovery
  3. Si vous n'attendez pas 60 secondes avant d'appuyer sur le bouton "Crash!!", Windows Error Reporting ne vous proposera pas de redémarrer.
  4. Attendez 60 Secondes avant le crash, puis redémarrer l'application comme indiqué
    redémarrage de l'application
  5. Un fichier temporaire nommée ~Vi1XXX.tmp a été crée, et sera utilisé comme argument à la fonctionRegisterApplicationRestart(PCWSTR pwzCommandline, DWORD dwFlags) lors du redémarrage de l'application

Haut de pageHaut de page

Quelques mots sur le code fournis :

Pour illustrer mon exemple, j'ai utilisé le langage de développement C++/CLI (qui cible la plate-forme .NET) pour son incroyable efficacité en termes d'interopérabilité entre le monde Natif et le Monde .NET. En effet c'est le seul langage qui permet de mixer dans le même fichier source, à la fois du code .NET (C++/CLI) et du code natif, facilitant ainsi l'utilisation de ces API Win32.

Vous retrouverez donc dans le code source un projet Windows Form C++/CLI (mais qui aurai pu être en C# ou en VB), qui contient la méthode de rappel Recover().

Cette méthode fait plusieurs choses :

  1. Appel l'API ApplicationRecoveryInProgress, pour savoir si l'utilisateur à annuler la récupération. Il est d'ailleurs important de l'appeler tout les 5 secondes, car Vista considéra que la récupération n'a pas fonctionnée et fermera l'application.
  2. Sérialise dans un fichier XML les données à récupérer
  3. Appel la fonction RegisterApplicationRestart en lui passant en paramètre le nom du fichier temporaire à utiliser lors du redémarrage
  4. Informe le système que la récupération est finie via la fonction ApplicationRecoveryFinished

Remarque :

Une bonne pratique consiste à régulièrement appeler la méthode de récupération même si tout va bien, afin que l'utilisateur n'est pas perdu trop de données au cas où le problème soit plus sérieux et qu'il ne laisse aucune chance à la méthode de récupération de s'exécuter (Bleu screen, problème driver, problème hardware etc…)

Pour faciliter l'utilisation de ces API, je les ai encapsulé dans une bibliothèque C++/CLI nommée HelperAPI, qui fait le pont entre le monde .NET et le monde natif. (Il est donc tout à fait possible de l'utiliser avec n'importe quel langage .NET sans utiliser la technologie PInvoke)

L'intérêt d'avoir mixer les deux mondes, est de démontrer que l'on peut très bien continuer à développer en C++ natif et améliorer son système, tout en l'intégrant facilement dans une nouvelle plate-forme comme .NET. Si vous avez des questions, n'hésitez pas à me contacter ericv@microsoft.com

 

Haut de pageHaut de page

Conclusion

Comme nous venons de le voir, il est maintenant assez facile de pouvoir ajouter plus de robustesse à son application en utilisant les API Application Recovery & Restart. Mais nous n'en resterons pas la en en terme de robustesse car dans les prochains articles, nous aborderons ce qu'il y a de nouveau dans Windows Error Reporting, le transactionnelle du noyau NT, les API Wait Chain Traversal et bien d'autres nouveautés, alors restez à l'écoute.

 

 

Haut de pageHaut de page