Windows Services Recovery ne redémarre pas le service

Je configure la récupération pour que les services Windows redémarrent avec un délai d’une minute après des échecs. Mais je ne l’ai jamais eu pour réellement redémarrer le service (même avec les erreurs les plus flagrantes).

J’ai un message dans EventViewer:

La description de l’ID d’événement (1) dans Source (MyApp.exe) est introuvable. L’ordinateur local peut ne pas avoir les informations de Registre nécessaires ou les fichiers DLL de message pour afficher les messages d’un ordinateur distant. Vous pourrez peut-être utiliser l’indicateur / AUXSOURCE = pour récupérer cette description; voir Aide et support pour plus de détails. Les informations suivantes font partie de l’événement: Violation d’access à l’adresse 00429874 dans le module ‘MyApp.exe’. Ecriture de l’adresse 00456704.

Y a-t-il autre chose que je dois faire? Y a-t-il quelque chose dans mon code (j’utilise Delphi) qui doit être défini pour activer cela?

Service Recovery est destiné à gérer le cas où un service se bloque – donc si vous allez à taskmgr et faites un clic droit sur “end process” sur votre processus de service, la logique de récupération doit démarrer. si votre service se ferme normalement (même s’il se termine par une erreur).

Le message eventvwr indique également que votre application a appelé l’API ReportEvent en spécifiant l’ID d’événement 1. Mais vous n’avez pas enregistré vos messages d’événement avec l’afficheur d’événements afin qu’il ne puisse pas convertir l’ID d’événement 1 en une chaîne de texte significative.

Service Recovery ne fonctionne que pour un appel inattendu à la sortie ( exit (-1) ). Car tout ce que nous utilisons pour arrêter le service de la manière habituelle ne fonctionnera pas pour la récupération. Si vous souhaitez arrêter le service et que vous souhaitez toujours que la récupération fonctionne, appelez exit (-1) et le message d’erreur apparaîtra comme “le service s’est arrêté avec une erreur inattendue”. Votre service redémarrera alors que le paramètre de récupération est défini.

Le Service Control Manager tentera de redémarrer votre service si vous le configurez pour qu’il soit redémarré par le SCM. Ceci est détaillé ici dans la documentation de la structure SERVICE_FAILURE_ACTIONS .

Un service est considéré comme ayant échoué lorsqu’il se termine sans signaler le statut SERVICE_STOPPED au contrôleur de service.

Cela peut être affiné en définissant le drapeau fFailureActionsOnNonCrashFailures la structure SERVICE_FAILURE_ACTIONS_FLAG , voir ici . Vous pouvez définir ce paramètre à partir de l’applet Services en cochant la case “Activer les actions pour les arrêts avec erreurs” dans l’onglet Récupération.

Si ce membre est VRAI et que le service a configuré des actions d’échec, les actions d’échec sont mises en queue si le processus de service se termine sans signaler l’état de SERVICE_STOPPED ou s’il entre dans l’état SERVICE_STOPPED, mais le membre dwWin32ExitCode . Si ce membre est FALSE et que le service a configuré des actions d’échec, les actions d’échec ne sont mises en queue que si le service se termine sans signaler l’état de SERVICE_STOPPED.

Ainsi, selon la façon dont vous avez structuré votre service, comment vous avez configuré vos actions en cas d’échec ET ce que vous faites lorsque vous avez votre “erreur fatale”, il suffit d’appeler ExitProcess() ou exit() et de retourner une valeur non nulle. Cependant, il est probablement plus sûr de s’assurer que votre service se termine sans le code traitant du SCM indiquant au SCM que votre service a atteint l’état SERVICE_STOPPED . Cela garantit que vos actions de défaillance se produisent TOUJOURS …

Si vous «tuez» le service du gestionnaire de tâches, vous avez oublié la logique de récupération. En tâche de fond, le gestionnaire de tâches «tue» le processus en «arrêtant le service». et comme vous pouvez le deviner, ce n’est pas une panne de service. Cela m’a forcé à le tuer vraiment avec Visual Studio. Dans le gestionnaire de tâches, cliquez avec le bouton droit sur le processus de service. Sélectionnez debug. Dans Visual studio, sélectionnez Debug-> Terminate All. Et maintenant, vous avez simulé un échec du service. Dans ce cas, la logique de récupération fonctionne correctement.