Compartir a través de


Transiciones de estado de servicio

Un servicio es responsable de notificar los cambios en su estado al administrador de control de servicios (SCM). Los programas de control de servicio y el sistema pueden averiguar el estado de un servicio solo desde el SCM, por lo que es importante que un servicio notifique su estado correctamente. Un servicio notifica su estado llamando a la función SetServiceStatus con un puntero a una estructura de SERVICE_STATUS totalmente inicializada. El miembro dwCurrentState de la estructura contiene el estado de servicio que se va a notificar.

El estado inicial de un servicio es SERVICE_STOPPED. Cuando el SCM inicia el servicio, establece el estado del servicio en SERVICE_START_PENDING y llama a la función ServiceMain del servicio. A continuación, el servicio completa su inicialización mediante una de las técnicas descritas en Service ServiceMain Function. Una vez que el servicio complete su inicialización y esté listo para empezar a recibir solicitudes de control, el servicio llama a SetServiceStatus para notificar SERVICE_RUNNING y especificar las solicitudes de control que el servicio está preparado para aceptar. La transición de SERVICE_START_PENDING a SERVICE_RUNNING indica a las herramientas de SCM y de supervisión de servicios que el servicio se ha iniciado correctamente. Si el servicio notifica un estado distinto de SERVICE_RUNNING, las herramientas de supervisión de servicio o SCM podrían marcar el servicio como si no se hubiera podido iniciar.

El SCM envía solo las solicitudes de control especificadas al servicio (excepto la solicitud de SERVICE_CONTROL_INTERROGATE, que siempre se envía). Para obtener una lista de las solicitudes de control que un servicio puede aceptar, consulte el miembro dwControlsAccepted de la estructura SERVICE_STATUS . Para obtener información sobre cómo registrarse para recibir eventos de dispositivo, consulte la función RegisterDeviceNotification .

El estado del servicio normalmente cambia como resultado de controlar una solicitud de control. Las solicitudes de control que hacen que el estado del servicio cambie incluyen SERVICE_CONTROL_STOP, SERVICE_CONTROL_PAUSE y SERVICE_CONTROL_CONTINUE. Si el servicio debe realizar un procesamiento largo para controlar cualquiera de estas solicitudes, debe crear un subproceso secundario para realizar el procesamiento largo e informar del estado pendiente correspondiente al SCM. (Para obtener el mejor rendimiento en Windows Vista y versiones posteriores de Windows, el servicio debe usar un subproceso de trabajo de un grupo de subprocesos para este fin). A continuación, el servicio debe notificar la transición de estado completada cuando finalice el procesamiento largo. Para obtener más información sobre cómo controlar las solicitudes de control, vea Service Control Handler Function.

Solo ciertas transiciones de estado de servicio son válidas. En el diagrama siguiente se muestran las transiciones válidas.

transiciones de estado de servicio válidas

El estado del servicio notificado al SCM determina cómo interactúa el SCM con el servicio. Por ejemplo, si un servicio notifica SERVICE_STOP_PENDING, el SCM no transmite más solicitudes de control al servicio porque este estado indica que el servicio se está cerrando. El siguiente estado notificado por el servicio debe ser SERVICE_STOPPED porque es el único estado válido después de SERVICE_STOP_PENDING. Sin embargo, si un servicio notifica una transición que no es válida, el SCM no produce un error en la llamada.

En el diagrama siguiente se muestran las transiciones de estado del servicio con más detalle, incluidas las solicitudes de control iniciadas por un programa de control de servicio (el cliente de servicio) y las llamadas a SetServiceStatus que un servicio realiza para notificar los cambios de estado en el SCM. Como se mencionó anteriormente, el SCM solo envía solicitudes de control que el servicio ha especificado que aceptará, por lo que es posible que un servicio no reciba todas las solicitudes que se muestran en el diagrama.

transiciones de estado del servicio en detalle

ControlService

ControlServiceEx

SetServiceStatus