¿Hay alguna forma de depurar completamente un servicio de Windows con Delphi?¿Cómo depurar un servicio de Windows con Delphi?
Respuesta
Sí, se encuentra: Debugging services: an easy way
Cómo se crea servicios con Delphi? Entonces tal vez también le molesta la forma que consume mucho tiempo de iniciar, reiniciar, matar y adjuntar a la aplicación del proceso de servicio cada vez. Bueno, hay remedio.
No necesita hacer esto. En su lugar, ejecute Delphi como una aplicación de sistema y haga algunas adaptaciones menores al código de servicio .
Sí, sí.
En el DPR:
Application.CreateForm(TMyService, MyService);
_ServiceInDebugMode := SysUtils.FindCmdLineSwitch('DEBUG', True);
if _ServiceInDebugMode then
DebugService(MyService)
else
SvcMgr.Application.Run;
DebugService es un procedimiento que crea una forma de depuración, un hilo de control de servicio y se inicia todo llamando Forms.Application.Run.
Puede comparar el hilo de control del servicio con el SCM (Service Control Manager) de Windows, el formulario de depuración con una aplicación que se comunica con el SCM (como services.msc) para iniciar y detener servicios. El servicio también debe tener su propio hilo (cadena de servicio) para responder a los códigos de control provenientes de SCM o nuestro hilo de control de servicio y uno o más hilos separados para hacer su trabajo real. Desea hilos separados para el trabajo real (en lugar de codificarlo en los controladores de eventos de su descendiente de TService) para asegurarse de que el hilo en el que se ejecuta el TService siempre responda libremente a los códigos de control del SCM y todavía puede detener y inicie el servicio aun cuando por casualidad a/el hilo de trabajo esté congelado.
Este enfoque también le permite depurar el código de la aplicación de servicio, pero implica una buena cantidad de código y colocar un par de ganchos en las funciones de la API de Windows para que funcionen correctamente. Demasiado para mostrar aquí a corto plazo. Tal vez lo escriba en un artículo algún día.
Mientras tanto, si no desea codificarlo usted solo, tiene dos opciones. Vaya con una biblioteca como SVCOM o la mencionada por Mick que lo haga todo por usted, o cuando esté en modo de depuración omita el código de servicio y "simplemente" comience su servicio como una aplicación de formularios "normal". Tendrá que desentrañar la funcionalidad real de su servicio del código de su descendiente/controladores de eventos, pero eso es algo que recomiendo de todos modos por las razones mencionadas anteriormente.
Tengo la misma aplicación con formularios y servicio. Con formas funciona. Con servicios no funciona. –
@Marjan Venema ¿En que unidad DebugService se encuentra? –
@SpongebobComrade no hay ninguno. Es algo que escribes tú mismo. Lo que debería hacer se menciona en el primer párrafo debajo del código. Verifique las otras respuestas para más información. –
Puede utilizar unitDebugService.pas de Colin Wilson's NT Low Level Utilities (página ya no está, available in the wayback machine)
y luego en el DPR:
begin
if (paramCount > 0) and (SameText(ParamStr(1), '-DEBUG')) then
begin
FreeAndNil (Application);
Application := TDebugServiceApplication.Create(nil);
end;
//... the rest of the normal DPR code
end.
De esta manera se puede ejecutar desde dentro de Delphi con la depuración (por establecer los parámetros del depurador del proyecto), usar el EXE como un servicio, o ejecutar desde la línea de comandos con el interruptor -DEBUG
, y.
Use Ejecutar -> Adjuntar para procesar. De esta manera puede depurar un servicio sin realizar ningún cambio en su código.La única parte engañosa tal vez es la depuración del código de inicio del servicio, porque la conexión puede requerir cierto tiempo, y el inicio debe ocurrir en 30 segundos (aunque puede ajustar Windows para permitir un tiempo más prolongado). Puede usar un retraso (sleep ...) para permitir que se adjunte a tiempo, o si solo necesita ver qué sucede, puede usar OutputDebugString() para imprimir en la salida de depuración (use Delphi Event View para verla).
He intentado esto, pero solo aparece la ventana de la CPU con los códigos de ensamblaje. –
'Adjuntar al proceso' funciona bien. Cuando el depurador se conecta por primera vez al proceso de servicio, la ventana de la CPU aparece, pero simplemente puede cerrarla y presionar F9 o el botón Ejecutar para continuar ejecutando el servicio normalmente, y luego puede depurar su código como sea necesario, como cualquier otro proyecto. –
Esto está funcionando bien. Si no desea que aparezca la ventana de la CPU, puede desmarcar la casilla de verificación 'pausa después de adjuntar'. – GolezTrol
He intentado esto, pero solo aparece la ventana de la CPU con los códigos de ensamblaje.
Entonces solo deberías resolver este problema.
Básicamente, para depurar un servicio Win2, hay pocas maneras:
- Uso "asociar al proceso" comando para adjuntar depurador para el servicio ya se está ejecutando. Puede insertar retrasos de inicio para tener tiempo de adjuntar depurador, si necesita adjuntar desde el principio. Sin embargo, también debería modificar el sistema para aumentar el tiempo de espera del servicio.
- Utilice "Image File Execution Options" registry key para ejecutar forzosamente el depurador de Delphi al arrancar el servicio. Se aplican las mismas consideraciones sobre los tiempos de espera del sistema.
- Servicio de conversión temporal en la aplicación habitual y ejecutarlo normalmente en el depurador. Puede volver a ejecutar IDE con una cuenta de usuario diferente para obtener más privilegios para el "servicio".
Si por algún motivo solo tiene vista de CPU de su servicio después de iniciar la depuración, esto significa que el depurador de Delphi no puede encontrar la información de depuración para su servicio. Ese es un problema diferente y debería buscar una solución para ello.
lo general, usted tiene que hacer:
- Asegúrese de que la carpeta de salida para su aplicación de servicio se establece en carpeta desde la que se cargará por el sistema. Es decir. si su servicio se encuentra en C: \ Windows \ System32 - luego configure la carpeta de salida en C: \ Windows \ System32. No copie el archivo .exe en otro lugar desde su carpeta de salida. Para 64 sistemas puedes probar alias (sysnative/SysWOW64) o nombre real. Creo que es mejor establecer la ruta de salida a la carpeta del proyecto y volver a registrar el servicio que se cargará desde la carpeta del proyecto.
- (Opcional) Establezca la ruta de salida para DCU en la misma carpeta que el archivo .exe.
- Borre todos sus archivos DCU.
- Asegúrese de habilitar las opciones de depuración en la página "Compilador" en las opciones del proyecto.
- (Opcional) Además, también puede incluir opciones TD32/RSM/MAP en la página "Enlazador".
- Asegúrese de que no hay un experto/extensión IDE, que puede modificar el archivo .exe, la información de depuración o la fecha de modificación del archivo para estos archivos.
- Asegúrese de que no haya archivos viejos (DCU/exe) en otras ubicaciones.
- Haga una reconstrucción completa (Proyecto/Construir todo).
- Ejecute su servicio.
Este método funciona muy bien. – Turrican
En realidad es bastante fácil. Simplemente use la directiva de compilador DEBUG estándar para comenzar el servicio como una aplicación de consola en lugar de un servicio.
program MyServiceApp;
{$ifdef DEBUG}
{$APPTYPE CONSOLE}
{$endif}
uses
System.SysUtils,
[..]
begin
{$ifdef DEBUG}
try
// In debug mode the server acts as a console application.
WriteLn('MyServiceApp DEBUG mode. Press enter to exit.');
// Create the TService descendant manually.
ServerContainer1 := TServerContainer.Create(nil);
// Simulate service start.
ServerContainer1.ServiceStart(ServerContainer1, MyDummyBoolean);
// Keep the console box running (ServerContainer1 code runs in the background)
ReadLn;
// On exit, destroy the service object.
FreeAndNil(ServerContainer1);
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
WriteLn('Press enter to exit.');
ReadLn;
end;
end;
{$else}
// Run as a true windows service (release).
if not Application.DelayInitialize or Application.Installing then
Application.Initialize;
Application.CreateForm(TServerContainer, ServerContainer1);
Application.Run;
{$endif}
end.
¡Esto es lejos, un muy buen enfoque! Necesitamos escribir código, en realidad, pero no hay unidades de 3ª parte, funciones o configuraciones de registro de Windows complicadas –
exactamente lo que estaba buscando. gracias. votado. –
- 1. ¿Cómo depurar un servicio de Windows utilizando puntos de interrupción?
- 2. Crear un servicio de Windows en delphi
- 3. Crear un servicio de Windows para abrir un programa- Delphi
- 4. Cómo depurar un archivo DLL en Delphi
- 5. Cómo depurar el servicio WCF?
- 6. Cómo depurar una aplicación Delphi con salida redirigida
- 7. Usando Ninject con un servicio de Windows
- 8. Servicio de Windows: no funciona en los momentos especificados (Delphi)
- 9. ¿Cómo hacer un servicio de Windows con parámetros?
- 10. Problema extraño con un servicio Windows .NET
- 11. ¿Cómo se puede depurar el servicio web?
- 12. Servicio de Windows terminado inesperadamente
- 13. Iniciar un proceso con credenciales de un servicio de Windows
- 14. Cómo depurar con Visual C++ 6 en Windows 7 x64?
- 15. ¿Cómo se puede depurar el método .NET Windows Service OnStart?
- 16. ¿Cómo puedo desactivar un servicio a través de Delphi?
- 17. ¿Cómo puedo depurar un servicio IIS local con Visual Studio ejecutándose como un usuario no administrador?
- 18. Delphi 2009: ¿Cómo comunicarse entre el servicio de Windows y la aplicación de escritorio en Vista?
- 19. Programe el servicio de Windows con Quartz.NET
- 20. Cómo depurar un servicio web alojado por un IIS en una aplicación de Silverlight
- 21. ClickOnce ¿implementar un servicio de Windows?
- 22. Cómo depurar un servicio WCF con dos aplicaciones de consola simultáneamente
- 23. Actualización automática de un servicio de Windows
- 24. Método más rápido de comunicación con un servicio de Windows
- 25. Aplicación de consola para comunicarse con un servicio de Windows
- 26. Cómo depurar una aplicación Delphi iOS FireMonkey en Xcode?
- 27. Problema al probar un servicio de Windows
- 28. ejecutar un servicio de Windows como una aplicación de consola
- 29. Consumir el servicio oData de Delphi
- 30. Crear un servicio de Windows en vb6
RunAsSys suena bien. El código de ejemplo en el artículo que enlazó usa definiciones condicionales para seleccionar el "modo". ¿Sabe si RunAsSys permite seleccionar el modo de depuración sin tener que reconstruir la aplicación? Es decir, ¿usar un parámetro de línea de comando para entrar en modo de depuración en lugar de ejecutarlo como un servicio? –
No estoy seguro, pero parece que usted mismo podría agregar esa funcionalidad. – Mick