Comment puis-je configurer la gestion de .NET UnhandledException dans un service Windows?

protected override void OnStart(ssortingng[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Thread.Sleep(10000); throw new Exception(); } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { } 

J’ai attaché un débogueur au code ci-dessus dans mon service Windows, en définissant un point d’arrêt dans CurrentDomain_UnhandledException, mais il n’a jamais été touché. L’exception s’affiche, indiquant qu’elle est non gérée, puis le service s’arrête. J’ai même essayé de mettre du code dans le gestionnaire d’événements, au cas où il serait optimisé.

N’est-ce pas la bonne façon de configurer la gestion des exceptions non gérées dans un service Windows?

Je suis arrivé à ce sujet un peu tard, mais je pensais que cela pourrait valoir la peine de fournir une explication qu’aucune des autres réponses ne donne.

La raison pour laquelle le gestionnaire CurrentDomain_UnhandledException n’est pas atteint dans l’exemple de code de l’OP est que la méthode OnStart est appelée en réponse à une commande Start du Gestionnaire de contrôle des services Windows (la commande est reçue et envoyée à cette méthode par l’implémentation ServiceBase du framework); toute exception lancée par OnStart est gérée dans la classe de base, consignée dans le journal des événements et convertie en un code d’état d’erreur renvoyé au SCM. L’exception ne se propage donc jamais au gestionnaire d’exceptions non géré de l’AppDomain.

Je pense que vous constaterez qu’une exception non gérée à partir d’un thread de travail dans votre service serait interceptée par le gestionnaire CurrentDomain_UnhandledException .

Dans un service Windows, vous ne voulez PAS exécuter beaucoup de code dans la méthode OnStart. Tout ce que vous voulez, c’est le code pour lancer votre thread de service, puis revenir.

Si vous le faites, vous pouvez gérer les exceptions qui se produisent dans votre thread de service.

par exemple

 public static void Start() { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException); running = true; ThreadStart ts = new ThreadStart(ServiceThreadBody); thread = new Thread(ts); thread.Name = "ServiceThread"; thread.Priority = ThreadPriority.BelowNormal; thread.Start(); } 

Sachez que ce sujet est un peu ancien, mais a pensé qu’il serait utile d’append des commentaires basés sur une expérience personnelle de développement de services Windows dans .NET. La meilleure approche consiste à éviter de développer autant que possible avec le Service Control Manager – pour cela, vous avez besoin d’un harnais simple qui imite la manière dont les services démarrent – quelque chose qui peut créer une instance de votre classe de service (que vous avez déjà dérivée de ServiceBase). ) et appelez vos méthodes OnStart, OnStop etc. Ce harnais peut être une application console ou une application Windows selon vos désirs.

C’est à peu près la seule façon dont j’ai trouvé des problèmes de démarrage de service de débogage dans .NET – l’interaction entre votre code, Visual Studio et le véritable Service Control Manager rend simplement le processus impossible.

HTH.

Juste curieux, que tentez-vous d’accomplir: éviter les pannes de service ou signaler des erreurs?

Pour le reporting, je pense que le mieux est d’append des instructions try / catch de haut niveau. Vous pouvez essayer de les enregistrer dans le journal des événements Windows et / ou dans un fichier journal.

Vous pouvez également définir la propriété ExitCode sur une valeur différente de zéro jusqu’à ce que vous arrêtez correctement le service. Si l’administrateur système démarre votre service à partir du panneau de configuration des services et que votre service s’arrête brusquement avec un code de sortie différent de zéro, Windows peut afficher un message d’erreur avec la description de l’erreur.

Lorsque je travaillais sur mon propre service Windows, cela s’arrêtait étrangement. Je pensais que c’était à cause d’une exception non prise en charge. En ce moment, j’attrape des exceptions non manipulées sur un fichier texte. Tout d’abord, vous devez créer un nouveau fichier ServiceLog.txt sur les emplacements C en raison de la journalisation des captures sur un fichier texte. Avec le codage ci-dessous, j’ai obtenu toutes les exceptions non manipulées avec eux.

 using System.Security.Permissions; using System.IO; [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)] protected override void OnStart(ssortingng[] args) { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler); ... Your codes... .... } void MyHandler(object sender, UnhandledExceptionEventArgs args) { Exception e = (Exception)args.ExceptionObject; WriteToFile("Simple Service Error on: {0} " + e.Message + e.StackTrace); } private void WriteToFile(ssortingng text) { ssortingng path = "C:\\ServiceLog.txt"; using (StreamWriter writer = new StreamWriter(path, true)) { writer.WriteLine(ssortingng.Format(text, DateTime.Now.ToSsortingng("dd/MM/yyyy hh:mm:ss tt"))); writer.Close(); } }