2

J'ai un service Windows que je voudrais recueillir des données de débogage sur l'utilisation d'Intellitrace - le problème est que vous ne pouvez pas déboguer un service Windows en le démarrant directement à partir de VS. J'ai le service installé, et la toute première déclaration dans Service.Start est "Debug.Break", ce qui me permet d'attacher VS. Toutefois, vous ne pouvez pas utiliser Intellitrace si un processus est déjà démarré lorsque vous vous connectez.Puis-je utiliser Intellitrace de VS2010 pour collecter des données pour un service Windows?

Est-ce que quelqu'un sait d'une solution de contournement pour cela?

Répondre

4

C'est possible avec un peu de travail. L'idée générale est de simuler une application console qui appellera les méthodes OnStart et OnStop du service. Ce n'est pas le point de départ et d'arrêt exact d'un service, mais j'espère que cela vous permettra de diagnostiquer votre problème. J'ai inclus un exemple de code pour vous donner une idée générale.

ConsoleMock.cs: 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using WindowsService1; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Service1 s1 = new Service1(); 
      while (true) 
      { 
       Console.WriteLine(">1 Start\n>2 Stop"); 
       string result = Console.ReadLine(); 
       if (result == "1") 
       { 
        var method = s1.GetType().GetMethod("OnStart", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
        method.Invoke(s1, new object[] { args }); 
       } 
       else if (result == "2") 
       { 
        var method = s1.GetType().GetMethod("OnStop", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
        method.Invoke(s1, new object[] { }); 
       } 
       else 
       { 
        Console.WriteLine("wrong command"); 
       } 
      } 
     } 
    } 
} 


Service.cs: 
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Diagnostics; 
    using System.Linq; 
    using System.ServiceProcess; 
    using System.Text; 
    using System.Threading; 

    namespace WindowsService1 
    { 
     public partial class Service1 : ServiceBase 
     { 
      private long serviceCounter; 
      private Thread workerThread; 

      public Service1() 
      { 
       InitializeComponent(); 
       serviceCounter = 0; 

      } 

      public void Worker() 
      { 
       while (true) 
       { 
        serviceCounter += 1; 
        System.Threading.Thread.Sleep(500); 

        try 
        { 
         throw new Exception(serviceCounter.ToString()); 
        } 
        catch (Exception) 
        { 
        } 
       } 
      } 

      protected override void OnStart(string[] args) 
      { 
       workerThread = new Thread(new ThreadStart(Worker)); 
       workerThread.Start(); 
      } 

      protected override void OnStop() 
      { 
       workerThread.Abort(); 
      } 
     } 
    } 
+0

Cela pourrait fonctionner pas moins comme un champion! Je l'ai effectivement utilisé pour créer une application stub tester mon service Windows sans avoir à attacher le débogueur manuellement - mon WinForm a juste un bouton de démarrage et d'arrêt qui utilise ce même code, et cela fonctionne parfaitement. Je vous ai donné trois upvotes si je pouvais! – SqlRyan

0

La technique d'Evan ne répond pas à la question originale.

Pour une solution, voir http://blogs.msdn.com/b/msaffer/archive/2011/02/23/using-intellitrace-with-services.aspx. Peu de temps créer un registre nom de la valeur multi-chaîne « Environnement » sous HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services * myservice * avec trois lignes

COR_ENABLE_PROFILING=1 
COR_PROFILER={301EC75B-AD5A-459C-A4C4-911C878FA196} 
VSLOGGERCPLAN=Put_here_the_path_to_your_CollectionPlan.xml