Quelle est la bonne façon pour un service Windows à l'échec?

J'ai hérité d'un service Windows écrit en C#. Dans de rares cas, il va mal. Cependant, il n'est pas clair du tout comment l'échec de bien. Ross Bennett états le problème élégamment à bytes.com. Par souci de simplicité, je vais juste citer ici.

Ohé, Les Gens!

J'ai cherché partout, pour cela,
mais je n'arrive pas à les secouer un
la documentation de la MSDN ou de
Google. J'ai passé en revue tous les .NET
article sur le développement de Services de Windows
dans la MSDN j'ai trouve.

Je suis le développement d'un Service Windows
application. Ce service de son lit
les données de configuration du système
registre (HKLM) où il a été déposé
par un autre "gestionnaire" de l'application. Pas de
problèmes là-bas.

Le service utilise un thread de travail à faire
ses travaux. Le thread est créé dans le
OnStart() et a/joint/cédées
dans le OnStop(). Encore une fois, pas de problèmes.

Tout fonctionne à merveille lorsque:

  1. L'administrateur système a tout mettre en place correctement, et
  2. l'étranger les ressources du réseau sont tous accessibles.

Mais bien sûr, nous, en tant que développeurs tout simplement
ne pouvez pas compter sur:

  1. L'administrateur système ayant tout mis en place correctement, ou
  2. l'étranger les ressources du réseau accessible.

Vraiment, ce que nous avons besoin est pour la
application de service à certains
de mourir sur son propre. Si un réseau
des ressources tombe en panne, nous avons besoin de l'
arrêt du service. Mais plus de la
point, nous avons besoin de la SCM à savoir qu'il a
arrêté sur son propre accord. SCM besoins
à savoir que le service a
"a échoué"...et n'a pas simplement été fermé
par quelqu'un.

L'appel de "retour" ou de jeter un
exception dans le "OnStart()" méthode
n'est même pas utile pour les services encore
dans le processus de démarrage.. Le SCM va
gaiement sur et le processus continue
cours d'exécution dans le Gestionnaire des Tâches--si
ce n'est pas en train de faire quoi que ce soit depuis
le thread de travail n'a jamais été créé
et a commencé.

À l'aide d'un ServiceController exemple
ne pas le faire, soit. Qui semble
le SCM comme un arrêt normal, et non pas une
défaillance de service. Aucun
les mesures de rétablissement ou de redémarrage de se produire.
(Aussi, il est MSDNful documentation
avertissement sur les dangers d'un
ServiceBase descendant à l'aide d'un
ServiceController pour rendre les choses
arriver avec lui-même.)

J'ai lu des articles où les gens ont été
bricoler avec PInvoking appels à
le code natif pour le
"Arrêté" de l'indicateur d'état dans le SCM. Mais
cela ne veut pas arrêter le processus de la
le service est en cours d'exécution à l'intérieur.

J'aimerais vraiment connaître la Destinée
De:

  1. La fermeture d'un service à partir de l'intérieur du service, là où
  2. La SCM est appropriatedly averti que le service est "Stoppée", et
  3. Le processus disparaît à partir du Gestionnaire des Tâches.

Solutions impliquant ServiceControllers
ne semble pas être le cas, si seulement
parce que 2 n'est pas satisfait. (Que l'
Cadre de la documentation spécifiquement
contraindicates faire qui porte un
beaucoup de poids, d'ailleurs.)

Je vous en serais reconnaissant de toutes les recommandations,
des pointeurs vers des documents ou même
raisonnée des conjectures. 🙂 Oh! Et
Je suis parfaitement heureux daccueillir que
J'ai manqué le point.

Très cordialement,

Ross Bennett