2008-10-03 17 views
5

Nous avons un SmartClient construit en C# qui reste stubornly ouvert lorsque le PC sur lequel il s'exécute est redémarré. Cela interrompt le processus de redémarrage sauf si l'utilisateur ferme le SmartClient pour la première fois ou s'il y a une autre intervention manuelle.C# .Net exe ne se ferme pas lorsque le PC est redémarré, ce qui empêche la machine de redémarrer

Cela provoque des problèmes lorsque l'équipe d'infrastructure installe à distance un nouveau logiciel qui nécessite un redémarrage de la machine.

Avez-vous des idées pour que l'application SmartClient reconnaisse l'événement d'arrêt/redémarrage de Windows et se mette à se tuer?

MISE À JOUR: Il s'agit d'une application hautement threadée avec plusieurs threads GUI. oui, plusieurs threads gui. C'est vraiment une consolidation de nombreux projets qui en soi pourraient être des applications autonomes - qui sont toutes lancées et gérées à partir d'un seul exe qui centralise ces méthodes de gestion et assure le suivi de ces threads. Je ne crois pas que l'utilisation de threads d'arrière-plan est une option.

+0

Exécutez-vous des tâches sur des threads non-fond? – Will

+0

Avez-vous accès au code source de l'application SmartClient? –

Répondre

5

OK, si vous avez accès à l'application, vous pouvez gérer l'événement SessionEnded.

... 
Microsoft.Win32.SystemEvents.SessionEnded +=new 
    Microsoft.Win32.SessionEndedEventHandler(shutdownHandler); 

... 

private void shutdownHandler(object sender, Microsoft.Win32.SessionEndedEventArgs e) { 
    // Do stuff 
} 
+1

Juste une note: Vous voulez probablement l'événement SessionEndING, pas le SessionEnded (si vous avez besoin d'abandonner les threads et de fermer les formulaires, etc.). – Sire

+0

+1 pour apprendre quelque chose de nouveau. – Ikaso

0

Normalement, une application .Net répondrait correctement - au moins, c'est le comportement «prêt à l'emploi». Si ce n'est pas le cas, il pourrait y avoir un certain nombre de choses qui se passent. Ma meilleure estimation sans en savoir plus sur votre programme est que vous avez un processus de longue durée allant dans le thread principal de l'interface utilisateur qui empêche l'application de répondre aux messages de la fenêtre.

+0

Ne sont pas des processus de longue durée mais ont Threading comme Catalin mentionné ci-dessus. Pourtant, cela ne répond pas vraiment à la question - je cherche vraiment un moyen de détecter quand la machine est en cours de redémarrage. – ScottCher

1

Ou peut-être que l'application .Net ignore les messages de fermeture ou de fermeture à dessein?

+0

ceci est un commentaire imo – Konstantinos

5

Ce thread doit continuer à s'exécuter pour empêcher la fermeture de votre application. Si vous utilisez un thread, une solution facile serait de le mettre en arrière-plan.

Un thread est un thread d'arrière-plan ou un thread de premier plan. Les threads d'arrière-plan sont identiques aux threads de premier plan, sauf que les threads d'arrière-plan n'empêchent pas un processus de se terminer. Une fois que tous les threads de premier plan appartenant à un processus se sont terminés, le Common Language Runtime termine le processus. Les threads d'arrière-plan restants sont arrêtés et ne se terminent pas.

http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

+0

En effet, ceci est une application filetée. Voir mise à jour de l'article original. Cependant, compte tenu de ce que nous faisons avec les threads, les arrière-plans sont-ils encore viables? C'est à dire, plusieurs threads de l'interface graphique. – ScottCher

1

fils d'arrière-plan était une solution rapide et sale, la meilleure solution est d'utiliser des objets de synchronisation (ManualResetEvent, Mutex ou autre chose) pour arrêter les autres fils; Ou bien garder une trace de toutes vos fenêtres ouvertes et envoyer WM_CLOSE message lorsque l'application principale se ferme.

Vous devez donner plus d'informations sur comment démarrer ces applications GUI. peut-être vous démarrez un fil pour chaque application et appelez Application.Run(new Form1());?

Vous pouvez également regarder dans la création d'un AppDomain pour chaque application GUI

5

Lorsqu'un utilisateur déconnecte ou Windows est en cours de fermeture, le message WM_QUERYENDSESSION est envoyé à toutes les fenêtres de niveau supérieur.See MSDN documentation here.

Le comportement par défaut d'une application WinForm en réponse à ce message est de déclencher l'événement FormClosing avec CloseReason == WindowsShutDown ou autres. Le gestionnaire d'événements peut cependant choisir d'être têtu et refuser de fermer l'application, ce qui maintient le système en marche.

Vérifiez les FormClosing gestionnaires de vos applications. Peut-être qu'il y a quelque chose là-dedans. J'ai déjà vu ce genre de truc plusieurs fois.