87 votes

Comment déboguer les services Windows dans Visual Studio ?

Est-il possible de déboguer les services Windows dans Visual Studio ?

J'ai utilisé un code comme

System.Diagnostics.Debugger.Break();

mais il donne une erreur de code comme :

J'ai obtenu deux erreurs d'événement : eventID 4096 VsJITDebugger et "Le service n'a pas répondu à la demande de démarrage ou de contrôle en temps opportun."

127voto

Chirag Points 408

Utilisez le code suivant dans la méthode OnStart du service :

System.Diagnostics.Debugger.Launch();

Choisissez l'option Visual Studio dans le message contextuel.

Remarque : Pour l'utiliser uniquement en mode Débogage, une directive de compilateur #if DEBUG peut être utilisée, comme suit. Cela empêchera le débogage accidentel en mode release sur un serveur de production.

#if DEBUG
    System.Diagnostics.Debugger.Launch();
#endif

23voto

Lasse V. Karlsen Points 148037

Vous devez séparer tout le code qui fera des choses du projet de service dans un projet séparé, puis faire une application de test que vous pouvez exécuter et déboguer normalement.

Le projet de service serait juste le shell nécessaire pour mettre en œuvre la partie de service de celui-ci.

14voto

Pauli Østerø Points 4708

Soit cela comme suggéré par Lasse V. Karlsen, soit mettre en place une boucle dans votre service qui attendra qu'un débogueur s'attache. Le plus simple est

while (!Debugger.IsAttached)
{
    Thread.Sleep(1000);
}

... continue with code

De cette façon, vous pouvez démarrer le service et à l'intérieur de Visual Studio, vous choisissez "Joindre au processus..." et vous joignez à votre service qui reprendra alors l'exution normale.

7voto

ta.speot.is Points 15157

Étant donné que ServiceBase.OnStart a une visibilité de protected, je suis allé sur la voie de la réflexion pour réaliser le débogage.

private static void Main(string[] args)
{
    var serviceBases = new ServiceBase[] {new Service() /* ... */ };

#if DEBUG
    if (Environment.UserInteractive)
    {
        const BindingFlags bindingFlags =
            BindingFlags.Instance | BindingFlags.NonPublic;

        foreach (var serviceBase in serviceBases)
        {
            var serviceType = serviceBase.GetType();
            var methodInfo = serviceType.GetMethod("OnStart", bindingFlags);

            new Thread(service => methodInfo.Invoke(service, new object[] {args})).Start(serviceBase);
        }

        return;
    }
#endif

    ServiceBase.Run(serviceBases);
}

Notez que Thread est, par défaut, un thread de premier plan. return Main pendant que les threads de faux-services sont en cours d'exécution ne mettra pas fin au processus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X