Partager via


Eric Vernié

Les API Application Recovery & Restart

Auteur : Eric Vernié relation technique développeurs

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, qu'au niveau API Win32 pour développeurs natifs. Et bien sachez que Windows 7 et Windows 2008 R2 sont deux systèmes d'exploitation basés sur leurs prédécesseurs et qui en reprennent les concepts.
Ces nouveautés, mettent en évidence 3 piliers fondamentaux de Windows

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

Sommaire de l'article

  1. Introduction
  2. Application Recovery & Restart
  3. Conclusion

 

>>Téléchargez le module au format Word

>> Téléchargez les codes sources

 

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, qu'au niveau API Win32 pour développeurs natifs. Et bien sachez que Windows 7 et Windows 2008 R2 sont deux systèmes d’exploitation basés sur leurs prédécesseurs et qui en reprennent les concepts.

Ces nouveautés, mettent en évidence 3 piliers fondamentaux de Windows

  • La robustesse
  • Laperformance
  • Lasécurité

Technologies utilisées:

C/C++

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

Visual Studio 2010

(Disponible en téléchargement ici)

Le kit de développement Windows 7

Haut de pageHaut de page  

 

Application Recovery & 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, et toutes autres erreurs.

Microsoft, est en mesure 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 :Windows Error Reporting dans Windows 7

Note : Par défaut le mode de signalement des erreurs de Windows 7, est configuré pour rechercher automatiquement une solution. Pour obtenir le mode de signalement comme sur la figure 1, allez dans le panneau de configuration, tapez choisir comme sur la figure suivante :

 


Sélectionnez choisir le mode de signalement des problèmes, puis cocher la case chaque fois qu’un problème se produit, me demander avant de rechercher les solutions comme sur la figure ci-dessous:

 

 

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 7 et Windows Serveur 2008 R2 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 ?

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)

Lors du 1er appel, le paramètre pwzCommandline, peut être nul. Il nous servira lors du second appel car nous lui passerons le chemin d’un fichier qui contient les données à récupérer.

Le second paramètre dwFlags indique 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 s’est terminé dû à 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 s’est terminé dû à l'installation de mise à jour
RESTART_NO_REBOOT
8
Ne pas redémarrer le processus si l'ordinateur a redémarré dû à 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 un redémarrage, si une erreur fatale survient, Windows Error Reporting vous propose de redémarrer l'application (Figure 2)

 

 

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, afin que Windows Error Reporting puisse le prendre en compte la demande.

 

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

Pour en savoir plus : https://msdn.microsoft.com/fr-fr/vstudio/bb984878.aspx

Si cette API est intéressante pour l'utilisateur, car l’application se relance d’elle-même, imaginez sa joie si les données qu’il vient de saisir n’ont pas été perdues, et qu’il n’a pas à les ressaisir une nouvelle fois.

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

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 nul 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 :

HRESULT hr=S_OK;



            hr = ::RegisterApplicationRecoveryCallback((APPLICATION_RECOVERY_CALLBACK)Recover,NULL,                                               RECOVERY_DEFAULT_PING_INTERVAL,



                                          0);



        if (FAILED(hr))



        {



//code omis



        }







//Méthode de rappel



DWORD 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://msdn.microsoft.com/fr-fr/library/aa373347.aspx

Note :

Avec Visual Studio 2010, Microsoft a rajouté cette fonctionnalité directement dans les MFC (Microsoft Foundation Classes). Pour en tirer profit, il suffira alors de cocher les bonnes cases lors de la création du projet.

 

 

Mais si votre projet est déjà créé, il suffira d’ajouter par exemple dans le constructeur de votre application la ligne suivante :
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;

Pour en savoir plus : https://msdn.microsoft.com/fr-fr/library/dd465232(VS.100).aspx

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, Windows 7, Windows Serveur 2008 et 2008 R2, 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 ajouter une image !!

 

 

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émarrez l'application comme indiqué

 

 

5)    Un fichier temporaire nommé ~Vi1XXX.tmp a été créé, et sera utilisé comme argument à la fonction RegisterApplicationRestart(PCWSTR pwzCommandline, DWORD dwFlags) lors du redémarrage de l'application

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 toutes les 5 secondes, car Windows 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.    Appelle 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 (Blue 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.
Remarque :
Pour les développeurs .NET, Microsoft met à disposition depuis peu un Wrapper nommé Windows Api Code pack que vous pourrez télécharger à cette adresse : https://code.msdn.microsoft.com/WindowsAPICodePack

L'intérêt d'avoir mixé 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.

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.

Dans le prochain article, nous aborderons plus en détails Windows Error Reporting, la manière de le personnaliser et surtout la nouvelle fonctionnalité d’enregistrement des problèmes Problem Steps Recorder qui permettra aux développeurs et aux testeurs d’analyser et de reproduire plus finement les problèmes lors d’un plantage.

Haut de pageHaut de page