Escribir un programa de servicio Win2000 usando Delphi
Resumen: este artículo presenta el uso de Delphi para escribir programas de servicio Win2000. Las clases involucradas son TServiceApplicatoin, TService, TServiceThread, etc.
Palabras clave: Servicio/servicio
1. Introducción a los servicios de Win2000
La aplicación de servicio es un programa en segundo plano que se ejecuta en WinNT. Cada aplicación de servicio puede contener varios servicios y cada servicio es uno de los subprocesos (el servicio también puede crear varios subservicios). Al utilizar los servicios, las aplicaciones pueden obtener permisos especiales y el usuario no finalizará directamente el programa a través del Administrador de tareas de Win2000, por lo que los servicios se utilizan a menudo para lograr algunos objetivos especiales.
A través de la herramienta de gestión de servicios en el panel de control de Win2000, podemos configurar/ver las características del servicio:
(1) Nombre del servicio; (2) Nombre para mostrar; (3) Descripción (4) Tipo de inicio;
Entre ellos, el nombre del servicio identifica el servicio.
Tome el programa C:/WINNT/System32/services.exe de Win2000 como ejemplo. Este archivo Exe corresponde a una aplicación de servicio y es la entidad visible del programa de servicio que contiene múltiples servicios (Servicio), como Alerter, Cliente Dhcp (DHCP), Messenger, etc. Cuando finalizamos un servicio, otros servicios en la Aplicación de servicio donde se encuentra el servicio no finalizan.
En Delphi, los ingenieros de Borland nos proporcionan TServiceApplication, TService, TServiceThread y otras clases, que encapsulan una gran cantidad de detalles y simplifican el desarrollo de programas de servicio.
2. Aplicación de servicio T
En Delphi, la clase TServiceApplication corresponde a la ServiceApplication mencionada anteriormente. Utilizando el entorno de desarrollo Delphi, creamos un nuevo proyecto de aplicación de servicio y creamos una clase heredada de TService. El objeto Aplicación en el archivo del proyecto es una instancia de TServiceApplication. Cada TServiceApplication contiene varios objetos TService, que corresponden exactamente a la relación cuantitativa mencionada anteriormente entre programas de servicio y servicios.
Al leer las definiciones de las clases TServiceApplication y TService, podemos saber que TServiceApplication hereda de la clase TComponent, TService proviene de la clase TDataModule y el objeto Aplicación es responsable de la creación y destrucción de cada objeto TService. Sigue el código a continuación
Aplicación.CreateForm(TService1, Servicio1);
Se puede encontrar que los propietarios de los objetos TService creados son todos objetos de Aplicación; en VCL FrameWork, el Propietario siempre es responsable de destruir cada objeto Componente (la clase TComponent de VCL adopta el modo Compuesto), por lo que TServiceApplication también destruirá cada objeto TService.
Siguiendo el código de TServiceApplication.Run, puede encontrar que TServiceApplication primero analiza los parámetros en ejecución e implementa la instalación y desinstalación del servicio. Luego, inicialice una matriz ServiceStartTable, que contiene el nombre del servicio y la entrada en ejecución de cada objeto de servicio; finalmente cree un objeto TServiceStartThread, que es un objeto de subproceso, y llame a la API: StartServiceCtrlDispatcher desde el subproceso para iniciar varios servicios especificados en ServiceStartTable; El hilo principal de ServiceApplication sigue realizando bucles y procesando mensajes, como recibir solicitudes para detener/pausar un servicio.
3. TServicio
La clase TService hereda de la clase TDataModule, lo que significa que podemos agregar una gran cantidad de controles VCL para lograr funciones enriquecidas. Además, también podemos manejar OnStart, OnPause, OnStop, OnContinue, OnCreate, OnShutDown y otros eventos. Lo que hay que explicar es: OnStop significa que el servicio se ha detenido y OnShutDown significa que ServiceApplication ha dejado de ejecutarse, lo que significa que otros servicios también se han cancelado y los significados de los dos son diferentes.
Como se mencionó anteriormente, ServiceApplication inicia cada servicio llamando a StartServiceCtrlDispatcher. StartServiceCtrlDispatcher inicia la entrada de TService, que es TService.Main. TService.Main primero registra el servicio y luego llama a TService.DoStart. TService.DoStart crea un objeto miembro interno TServiceThread, que es un objeto de subproceso; al examinar TServiceThread.Execute, podemos saber que cuando procesamos TService1.OnExecute, TService delegará todas las solicitudes al objeto miembro TServiceThread para su procesamiento. El método predeterminado maneja todas las solicitudes.
TService.ServiceExecute es el contenido principal de TService. Para que un servicio se ejecute normalmente, además de ocuparse de los objetivos en los que necesita centrarse (como escuchar un determinado puerto, realizar una determinada tarea, etc.), también debe responder a comandos/solicitudes externas: como finalizar, pausar y reanudar el servicio. Por lo tanto, puede considerar crear un hilo dedicado para completar esta tarea y manejar comandos/solicitudes externos en ServiceExecute. Entonces el código es el siguiente:
mientras no esté terminado, comience
ServiceThread.ProcessRequests(Falso);
fin;
Por supuesto, también puede manejar ciertas tareas en OnExecute, como escuchar un determinado puerto, pero esto a menudo resulta en que el Servicio no pueda responder a Detener/Pausar y otras solicitudes de manera oportuna. Cuando se completa OnExecute, el servicio realmente ha completado su tarea y está a punto de finalizar (terminar).
Referencias:
MSDN, código fuente de Delphi VCL, documentación de ayuda de Delphi