Existe-t-il un moyen plus simple de parcourir le code que de démarrer le service via le Gestionnaire de contrôle des services Windows, puis d'attacher le débogueur au thread? C'est un peu lourd et je me demande s'il existe une approche plus simple.
c#
debugging
windows-services
Matthias
la source
la source
Réponses:
Si je veux déboguer rapidement le service, je tombe juste
Debugger.Break()
dedans. Lorsque cette ligne est atteinte, elle me ramènera à VS. N'oubliez pas de supprimer cette ligne lorsque vous avez terminé.MISE À JOUR: Comme alternative aux
#if DEBUG
pragmas, vous pouvez également utiliser l'Conditional("DEBUG_SERVICE")
attribut.Sur votre
OnStart
, appelez simplement cette méthode:Là, le code ne sera activé que lors des builds de débogage. Pendant que vous y êtes, il peut être utile de créer une configuration de build distincte pour le débogage du service.
la source
Je pense également que le fait d'avoir une "version" distincte pour une exécution normale et en tant que service est le chemin à parcourir, mais est-il vraiment nécessaire de dédier un commutateur de ligne de commande séparé à cet effet?
Ne pourriez-vous pas simplement faire:
Cela aurait "l'avantage", que vous pouvez simplement démarrer votre application via un double-clic (OK, si vous en avez vraiment besoin) et que vous pouvez simplement cliquer F5dans Visual Studio (sans avoir besoin de modifier les paramètres du projet pour inclure cette
/console
option).Techniquement, il
Environment.UserInteractive
vérifie si leWSF_VISIBLE
drapeau est défini pour la station Windows actuelle, mais y a-t-il une autre raison pour laquelle il reviendraitfalse
, à part d'être exécuté en tant que service (non interactif)?la source
System.Diagnostics.Debugger.IsAttached
place deEnvironment.UserInteractive
.Lorsque j'ai mis en place un nouveau projet de service il y a quelques semaines, j'ai trouvé ce message. Bien qu'il y ait beaucoup de bonnes suggestions, je n'ai toujours pas trouvé la solution que je voulais: la possibilité d'appeler les classes de service
OnStart
et lesOnStop
méthodes sans aucune modification des classes de service.La solution que j'ai trouvée utilise le
Environment.Interactive
mode d'exécution sélectionné, comme suggéré par d'autres réponses à ce post.L'
RunInteractive
assistant utilise la réflexion pour appeler les méthodes protégéesOnStart
etOnStop
:C'est tout le code requis, mais j'ai également écrit une procédure pas à pas avec des explications.
la source
walk through
) est de vous assurer d'entrer dans les propriétés du projet et de changer le type de sortieConsole Application
avant d'essayer de compiler et d'exécuter. Trouvez-le surProject Properties -> Application -> Output type -> Console Application
. De plus, pour que cela fonctionne correctement pour moi, j'ai fini par devoir exécuter l'application à l'aide de lastart
commande. Ex:C:\"my app name.exe" -service
ne fonctionnerait pas pour moi. Au lieu de cela, j'ai utiliséC:\start /wait "" "my app name.exe" -service
Parfois, il est important d'analyser ce qui se passe lors du démarrage du service. La connexion au processus n'aide pas ici, car vous n'êtes pas assez rapide pour connecter le débogueur pendant le démarrage du service.
La réponse courte est, j'utilise les 4 lignes de code suivantes pour ce faire:
Ceux-ci sont insérés dans la
OnStart
méthode du service comme suit:Pour ceux qui ne l'ont pas encore fait, j'ai inclus des conseils détaillés ci - dessous , car vous pouvez facilement rester coincé. Les conseils suivants se réfèrent à Windows 7x64 et Visual Studio 2010 Team Edition , mais devraient également être valables pour d'autres environnements.
Important: déployez le service en mode "manuel" (à l'aide de l'
InstallUtil
utilitaire à partir de l'invite de commande VS ou exécutez un projet d'installation du service que vous avez préparé). Ouvrez Visual Studio avant de démarrer le service et chargez la solution contenant le code source du service - configurez des points d'arrêt supplémentaires selon vos besoins dans Visual Studio - puis démarrez le service via le panneau de configuration du service.En raison du
Debugger.Launch
code, cela provoquera une boîte de dialogue "Une exception Microsoft .NET Framework non gérée s'est produite dans Servicename.exe ." apparaître. Cliquez comme indiqué sur la capture d'écran: Yes, debug Servicename.exeEnsuite, surtout dans Windows 7 UAC peut vous inviter à entrer les informations d'identification d'administrateur. Entrez-les et procédez avec Yes:
Après cela, la fenêtre bien connue du débogueur Visual Studio Just-In-Time apparaît. Il vous demande si vous souhaitez déboguer à l'aide du débogueur supprimé. Avant de cliquer Yes, sélectionnez que vous ne voulez pas ouvrir une nouvelle instance (2e option) - une nouvelle instance ne serait pas utile ici, car le code source ne serait pas affiché. Vous sélectionnez donc à la place l'instance Visual Studio que vous avez ouverte:
Après avoir cliqué Yes, après un certain temps, Visual Studio affiche la flèche jaune à droite de la ligne où se trouve l'
Debugger.Launch
instruction et vous pouvez déboguer votre code (méthodeMyInitOnStart
, qui contient votre initialisation).Appuyez sur pour F5continuer l'exécution immédiatement, jusqu'à ce que le prochain point d'arrêt que vous avez préparé soit atteint.
Astuce: pour que le service continue de fonctionner, sélectionnez Déboguer -> Détacher tout . Cela vous permet d'exécuter un client communiquant avec le service une fois qu'il a démarré correctement et que vous avez terminé de déboguer le code de démarrage. Si vous appuyez sur Shift+F5 (arrêtez le débogage), cela mettra fin au service. Au lieu de cela, vous devez utiliser le Panneau de configuration du service pour l'arrêter.
Notez que
Si vous créez une version, le code de débogage est automatiquement supprimé et le service s'exécute normalement.
J'utilise
Debugger.Launch()
, qui démarre et attache un débogueur . J'ai également testéDebugger.Break()
, ce qui n'a pas fonctionné , car il n'y a pas encore de débogueur attaché au démarrage du service (provoquant "Erreur 1067: le processus s'est terminé de manière inattendue." ).RequestAdditionalTime
définit un délai plus long pour le démarrage du service (il ne retarde pas le code lui-même, mais poursuivra immédiatement l'Debugger.Launch
instruction). Sinon, le délai par défaut pour démarrer le service est trop court et le démarrage du service échoue si vous n'appelez pasbase.Onstart(args)
assez rapidement à partir du débogueur. Pratiquement, un délai de 10 minutes évite que vous voyez le message " le service n'a pas répondu ..." immédiatement après le démarrage du débogueur.Une fois que vous vous y êtes habitué, cette méthode est très facile car elle vous oblige simplement à ajouter 4 lignes à un code de service existant, vous permettant ainsi de prendre rapidement le contrôle et de déboguer.
la source
base.RequestAdditionalTime(600000)
empêchera le contrôle de service de mettre fin au service pendant 10 minutes s'il n'appelle pasbase.OnStart(args)
dans ce délai). En dehors de cela, je me souviens que l'UAC abandonnera également si vous n'entrez pas les informations d'identification d'administrateur après un certain temps (je ne sais pas combien de secondes exactement, mais je pense que vous devez l'entrer dans une minute, sinon UAC abandonne) , qui mettra fin à la session de débogage.Ce que je fais habituellement, c'est encapsuler la logique du service dans une classe distincte et commencer celle-ci à partir d'une classe 'runner'. Cette classe de runner peut être le service réel ou simplement une application console. Votre solution a donc (au moins) 3 projets:
la source
Cette vidéo YouTube de Fabio Scopel explique très bien comment déboguer un service Windows ... la méthode actuelle de le faire commence à 04h45 dans la vidéo ...
Voici le code expliqué dans la vidéo ... dans votre fichier Program.cs, ajoutez les trucs pour la section Debug ...
Dans votre fichier Service1.cs, ajoutez la méthode OnDebug () ...
Fondamentalement, vous devez créer un
public void OnDebug()
qui appelle leOnStart(string[] args)
car il est protégé et n'est pas accessible à l'extérieur. Levoid Main()
programme est ajouté avec un#if
préprocesseur avec#DEBUG
.Visual Studio définit
DEBUG
si le projet est compilé en mode débogage, ce qui permettra à la section de débogage (ci-dessous) de s'exécuter lorsque la condition est vraieEt il fonctionnera comme une application console, une fois que les choses vont bien, vous pouvez changer le mode
Release
et laelse
section régulière déclenchera la logiquela source
METTRE À JOUR
Cette approche est de loin la plus simple:
http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx
Je laisse ma réponse originale ci-dessous pour la postérité.
Mes services ont tendance à avoir une classe qui encapsule une minuterie car je veux que le service vérifie à intervalles réguliers s'il y a du travail à faire.
Nous renouvelons la classe et appelons StartEventLoop () pendant le démarrage du service. (Cette classe peut également être facilement utilisée à partir d'une application console.)
L'effet secondaire agréable de cette conception est que les arguments avec lesquels vous configurez le minuteur peuvent être utilisés pour avoir un délai avant que le service ne commence réellement à fonctionner, de sorte que vous ayez le temps d'attacher un débogueur manuellement.
J'ai aussi l'habitude de faire ce qui suit (déjà mentionné dans les réponses précédentes mais avec les drapeaux du compilateur conditionnel [#if] pour éviter qu'il ne se déclenche dans une version Release).
J'ai arrêté de le faire de cette façon parce que parfois nous oublions de compiler Release et d'avoir une pause de débogage dans une application fonctionnant sur une démo client (embarrassante!).
la source
// do something
prend plus de 30 minutes?la source
OnStart
estprotected
et vous ne pouvez pas modifier le niveau d'accès :(Vous pouvez également démarrer le service via l'invite de commande (sc.exe).
Personnellement, j'exécuterais le code en tant que programme autonome dans la phase de débogage, et lorsque la plupart des bogues sont résolus, passez à l'exécution en tant que service.
la source
Ce que j'avais l'habitude de faire était d'avoir un commutateur de ligne de commande qui démarrerait le programme en tant que service ou en tant qu'application régulière. Ensuite, dans mon IDE, je réglais le commutateur pour pouvoir parcourir mon code.
Avec certaines langues, vous pouvez réellement détecter s'il s'exécute dans un IDE et effectuer ce changement automatiquement.
Quelle langue utilisez-vous?
la source
Utilisez le TopShelf bibliothèque .
Créez une application console puis configurez la configuration dans votre Main
Pour déboguer votre service, appuyez simplement sur F5 dans Visual Studio.
Pour installer le service, tapez cmd "install console.exe"
Vous pouvez ensuite démarrer et arrêter le service dans le gestionnaire de services Windows.
la source
Je pense que cela dépend du système d'exploitation que vous utilisez, Vista est beaucoup plus difficile à attacher aux services, en raison de la séparation entre les sessions.
Les deux options que j'ai utilisées dans le passé sont:
J'espère que cela t'aides.
la source
J'aime pouvoir déboguer tous les aspects de mon service, y compris toute initialisation dans OnStart (), tout en l'exécutant avec un comportement de service complet dans le cadre du SCM ... pas de mode "console" ou "application".
Je le fais en créant un deuxième service, dans le même projet, à utiliser pour le débogage. Le service de débogage, lorsqu'il est démarré comme d'habitude (c'est-à-dire dans le plugin MMC de services), crée le processus hôte de service. Cela vous donne un processus auquel attacher le débogueur même si vous n'avez pas encore démarré votre véritable service. Après avoir attaché le débogueur au processus, démarrez votre véritable service et vous pouvez le pénétrer n'importe où dans le cycle de vie du service, y compris OnStart ().
Parce qu'il nécessite une intrusion de code très minimale, le service de débogage peut facilement être inclus dans votre projet de configuration de service et est facilement supprimé de votre version de production en commentant une seule ligne de code et en supprimant un seul programme d'installation de projet.
Détails:
1) En supposant que vous implémentez
MyService
, créez égalementMyServiceDebug
. Ajoutez les deux auServiceBase
tableauProgram.cs
comme ceci:2) Ajoutez le service réel ET le service de débogage au programme d'installation du projet pour le projet de service:
Les deux services (réel et débogage) sont inclus lorsque vous ajoutez la sortie du projet de service au projet d'installation du service. Après l'installation, les deux services apparaîtront dans le plugin MMC service.msc.
3) Démarrez le service de débogage dans MMC.
4) Dans Visual Studio, attachez le débogueur au processus démarré par le service de débogage.
5) Démarrez le vrai service et profitez du débogage.
la source
Lorsque j'écris un service, je mets toute la logique du service dans un projet dll et crée deux "hôtes" qui appellent dans cette dll, l'un est un service Windows et l'autre est une application en ligne de commande.
J'utilise l'application de ligne de commande pour le débogage et attache le débogueur au service réel uniquement pour les bogues que je ne peux pas reproduire dans l'application de ligne de commande.
Si vous utilisez cette approche, souvenez-vous simplement que vous devez tester tout le code lors de l'exécution dans un service réel, tandis que l'outil de ligne de commande est une bonne aide au débogage, c'est un environnement différent et il ne se comporte pas exactement comme un vrai service.
la source
Lors du développement et du débogage d'un service Windows, je l'exécute généralement en tant qu'application console en ajoutant un paramètre de démarrage / console et en le vérifiant. Rend la vie beaucoup plus facile.
la source
Que diriez-vous de Debugger.Break () sur la première ligne?
la source
Pour déboguer les services Windows, je combine GFlags et un fichier .reg créé par regedit.
Ou enregistrez les extraits de code suivants et remplacez servicename.exe par le nom de l'exécutable souhaité.
debugon.reg:
debugoff.reg:
la source
Pour la programmation de petites choses de routine, j'ai fait une astuce très simple pour déboguer facilement mon service:
Au démarrage du service, je vérifie un paramètre de ligne de commande "/ debug". Si le service est appelé avec ce paramètre, je ne fais pas le démarrage habituel du service, mais plutôt démarre tous les écouteurs et affiche simplement une boîte de message "Débogage en cours, appuyez sur ok pour terminer".
Donc, si mon service est démarré de la manière habituelle, il démarrera en tant que service, s'il est démarré avec le paramètre / debug de la ligne de commande, il agira comme un programme normal.
Dans VS, je vais simplement ajouter / debug comme paramètre de débogage et démarrer directement le programme de service.
De cette façon, je peux facilement déboguer pour la plupart des petits problèmes. Bien sûr, certaines choses devront encore être déboguées en tant que service, mais pour 99%, cela suffit.
la source
la source
J'utilise une variante de la réponse de JOP. À l'aide des paramètres de ligne de commande, vous pouvez définir le mode de débogage dans l'EDI avec les propriétés du projet ou via le gestionnaire de services Windows.
la source
Pour le dépannage sur le programme de service Windows existant, utilisez 'Debugger.Break ()' comme d'autres gars l'ont suggéré.
Pour le nouveau programme Windows Service, je suggère d'utiliser la méthode de James Michael Hare http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template- redux.aspx
la source
Placez votre déjeuner de débogueur n'importe où et attachez Visualstudio au démarrage
Vous devez également démarrer VS en tant qu'Administrateur et vous devez autoriser qu'un processus puisse être débogué automatiquement par un utilisateur différent (comme expliqué ici ):
la source
Utilisez le projet de modèle de service Windows C # pour créer une nouvelle application de service https://github.com/HarpyWar/windows-service-template
Le mode console / service est détecté automatiquement, l'installateur / désinstallateur automatique de votre service et plusieurs des fonctionnalités les plus utilisées sont inclus.
la source
Voici la méthode simple que j'ai utilisée pour tester le service, sans aucune méthode supplémentaire de «débogage» et avec des tests unitaires VS intégrés.
la source
la source
Vous avez deux options pour effectuer le débogage.
Veuillez consulter CET article de blog que j'ai créé pour le sujet.
la source
Il suffit de coller
n'importe où dans votre code.
Par exemple ,
Il frappera
Debugger.Break();
lorsque vous exécuterez votre programme.la source
La meilleure option est d'utiliser le ' System.Diagnostics espace de noms ».
Insérez votre code dans le bloc if else pour le mode de débogage et le mode de libération comme indiqué ci-dessous pour basculer entre le mode de débogage et le mode de libération dans Visual Studio,
la source