¿Cómo depurar el método OnStart del servicio .NET de Windows?

Tengo un código escrito en .NET que solo falla cuando se instala como un servicio de Windows. El fallo no permite que el servicio se inicie. No puedo entender cómo puedo entrar en el método OnStart.

Cómo: depurar las aplicaciones de servicio de Windows da una pista tentadora:

Adjuntar al proceso del servicio le permite depurar la mayoría pero no todo el código del servicio; por ejemplo, debido a que el servicio ya se ha iniciado, no puede depurar el código en el método OnStart del servicio de esta manera o el código en el método principal que se utiliza para cargar el servicio. Una forma de evitar esto es crear un segundo servicio temporal en su aplicación de servicio que existe solo para ayudar en la depuración. Puede instalar ambos servicios y luego iniciar este servicio “ficticio” para cargar el proceso de servicio. Una vez que el servicio temporal ha iniciado el proceso, puede usar el menú Depurar en Visual Studio para adjuntarlo al proceso de servicio.

Sin embargo, no estoy claro cómo es exactamente que se supone que debe crear el servicio ficticio para cargar el proceso de servicio.

Una cosa que podría hacer como solución temporal es lanzar el depurador como la primera línea de código en OnStart

System.Diagnostics.Debugger.Launch() 

Esto le pedirá el depurador que desea utilizar. Simplemente tenga la solución ya abierta en Visual Studio y elija esa instancia de la lista.

Tiendo a agregar un método como este:

  [Conditional("DEBUG")] private void AttachDebugger() { Debugger.Break(); } 

solo se activará en las construcciones de depuración de su proyecto y pausará la ejecución y le permitirá adjuntar el depurador.

Una vez que haya instalado un servicio utilizando installutil.exe , puede modificar los Start Parameters para saltar al depurador si se inicia el servicio:

introduzca la descripción de la imagen aquí

Cuando inicie el servicio manualmente con el parámetro -debugWithVisualStudio (o simplemente -d ), detectará automáticamente el proyecto correcto y activará el depurador interactivo en Visual Studio:

introduzca la descripción de la imagen aquí

Para admitir esta funcionalidad, cambie la función OnStart() :

 ///  /// Executed when the service is started. ///  /// Command line arguments. protected override void OnStart(string[] args) { try { //How to debug when running a Windows Service: // 1. Right click on the service name in Windows Service Manager. // 2. Select "Properties". // 3. In "Start Parameters", enter "-d" (or "-debugWithVisualStudio"). // 4. Now, when you start the service, it will fire up Visual Studio 2012 and break on the line below. // 5. Make sure you have UAC (User Access Control) turned off, and have Administrator privileges. #if DEBUG if (((ICollection)args).Contains("-d") || ((ICollection)args).Contains("-debugWithVisualStudio")) { Debugger.Launch(); // Launches VS2012 debugger. } #endif ShellStart(args); base.OnStart(args); } catch (Exception ex) { // Log exception here. } } 

(opcional) Si desea limitarse a la línea exacta de código donde el servicio está generando un error, active las excepciones desde el menú de Visual Studio DEBUG .. Exceptions . Cuando continúe la depuración, se interrumpirá en la línea exacta que está lanzando la excepción.

introduzca la descripción de la imagen aquí

¡Funciona bien!

 protected override void OnStart(string[] args) { System.Diagnostics.Debugger.Launch(); } 

Las opciones anteriores no parecían funcionar en Windows 8.

He añadido Thread.Sleep (15000); en mi método OnStart () y establezca un punto de interrupción en la siguiente línea del código. Esto me dio 15 segundos para adjuntar el depurador VS a mi proceso después de iniciar el servicio y me permitió depurar el método OnStart () muy bien.

Puedes agregar una línea de código como esta:

 System.Diagnostics.Debugger.Break() 

que abrirá una ventana que le pedirá que elija qué depurador usar para depurar, por ejemplo, permitiéndole adjuntar con Visual Studio y entrar en el código.

ver:

http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break.aspx

Es posible configurar un proyecto complementario para el Servicio de Windows que se ejecuta como una aplicación de consola, pero que accede a los métodos del servicio utilizando Reflection. Consulte aquí para obtener detalles y un ejemplo: http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/ .

Utilice el siguiente Código en el Método de Inicio de Servicio:

 System.Diagnostics.Debugger.Launch(); 

Elija la opción Visual Studio del mensaje emergente. Recuerde ejecutar Visual Studio como administrador.

Nota: Para usarlo solo en el modo de depuración, se puede usar la directiva del comstackdor DEIFUG #if, de la siguiente manera. Esto evitará la depuración accidental o en modo de lanzamiento en el servidor de producción.

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

Como han señalado otros, tiene que agregar una interrupción del depurador al método OnStart:

 #if DEBUG System.Diagnostics.Debugger.Break() #endif 

También inicie VisualStudio como administrador y permita que un proceso distinto pueda ser depurado automáticamente por un usuario diferente (como se explica aquí ):

 reg add "HKCR\AppID\{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f 

(También expliqué esto aquí: https://stackoverflow.com/a/35715389/5132456 )

Sé que es tarde, pero así es como manejamos la depuración de los servicios de Windows

Primero crea una clase que actuará como el servicio.

Agregue los métodos apropiados para iniciar, detener, pausar, etc.

Agregue un formulario de Windows al proyecto de servicio.

En el código de servicio, cree la clase de servicio creada anteriormente y realice las llamadas necesarias para iniciar y detener el servicio en la clase ServiceBase

Abra el Program.cs y agregue lo siguiente

 #if DEBUG [STAThread] #endif static void Main() { try { #if DEBUG Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new DebugForm()); #else ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new YourWindowsService() }; ServiceBase.Run(ServicesToRun); #endif } catch (Exception e) { logger.Error(DateTime.Now.ToString() + " - " + e.Source + " - " + e.ToString() + "\r\n------------------------------------\r\n"); } } 

Cuando se ejecuta en modo DEBUG, se abrirá el formulario de Windows. Solo recuerda construir en el modo Release cuando termines. Por supuesto, la variable de comstackción condicional puede ser lo que quieras. Incluso podría crear proyectos separados, por lo que la forma de depuración es su propio proyecto.

Espero que esto ayude

También puede probar el método System.Diagnostics.Debugger.Launch () . Ayuda a llevar el puntero del depurador a la ubicación especificada y luego puede depurar su código.

Antes de este paso , instale su service.exe usando la línea de comandos del indicador de comandos de Visual Studio – installutil projectservice.exe

Luego inicie su servicio desde el Panel de control -> Herramientas administrativas -> Administración de computadoras -> Servicio y aplicación -> Servicios -> Nombre de su servicio

Intenta agregar Debugger.Break dentro del método problemático. Cuando se inicie el servicio, se lanzará una excepción y las viudas deberán ofrecer la depuración mediante Visual Studio.

Por lo general, tengo una aplicación de consola que pretende ser el SCM, por ejemplo, las llamadas Iniciar, Detener, a las que puedo oprimir F5 para mis propósitos principales de encoding / depuración, y utilizar Debugger.Break para la depuración cuando el servicio se ha instalado y se ha iniciado a través de SCM.

Significa un poco más de trabajo, para empezar, tengo una biblioteca de clase que contiene todo el código de servicio, con una clase que expone Inicio y Parada a la que pueden llamar tanto la clase de Servicio de Windows como la aplicación de consola.

Mate

Si agrega Debugger.Launch () en su método OnStart y no funciona, podría tener el mismo problema que tuve, es decir, la excepción se estaba produciendo en el constructor, por lo que nunca se llamó a OnStart. (bofetada)

(perdón si esto debió haber sido un comentario en la respuesta de otra persona, pero no tengo suficiente credibilidad para hacer comentarios)

Antes de entrar en el tema uno aconseja. Siempre usa el registro especialmente si eres desarrollador del lado del servidor. Debido a que hay una cierta condición que es posible que no puedas producir al depurar el código en Visual Studio.

Volviendo al tema, uso Envoirnment.UserInteractive flag Esto es muy útil, vea mi código a continuación.

 public static void Main(string[] args) { if (System.Environment.UserInteractive) { string parameter = string.Concat(args); switch (parameter) { case "--install": ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); break; case "--uninstall": ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); break; default: WindowsService service = new WindowsService(); service.OnStart(args); Console.ReadKey(); service.OnStop(); break; } } else { ServiceBase.Run(new WindowsService()); } } 

Desde Visual Studio obtendrás la opción UserInteractive flag, así que la ejecutaría como una aplicación de consola. Además, incluso puedes ejecutar la comstackción del producto haciendo doble clic en ella y adjuntando el depurador si quieres probarla.

Tengo una forma interesante de hacer esto. Agrego otra configuración llamada DebugNoService.

   .\ false 285212672 false   DEBUG;TRACE;DEBUGNOSERVICE   true 4096 false   false false false false 4 full prompt false  

Yo uso la directiva #if. ProjectInstaller.cs

 #if !DEBUGNOSERVICE static void Main() { System.ServiceProcess.ServiceBase[] ServicesToRun; ..... } #endif 

Agrego un formulario de Windows y también envuelvo el formulario de Windows

 #if DEBUGNOSERVICE ... static void Main() { Form form; Application.EnableVisualStyles(); Application.DoEvents(); form = new (); Application.Run(form); } ... #endif 

Dependiendo de la configuración seleccionada, el código se ejecuta como una aplicación de formulario de Windows que se puede depurar fácilmente o como un servicio.

Parece mucho trabajo, pero siempre ha funcionado y hace que la depuración del código sea muy fácil. Puede tener todo tipo de resultados agregados al formulario para que pueda verlo ejecutarse.