Parece que en las versiones de Windows posteriores a Windows 7 (sin verificar, pero según la experiencia más reciente con Windows Server 2012 R2), el Administrador de control de servicios (SCM) es más estricto.
Mientras que en Windows 7 solo genera otro proceso, ahora está verificando si el proceso de servicio aún está disponible y puede devolver ERROR_SERVICE_MARKED_FOR_DELETE (1072) para cualquier llamada posterior a CreateService / DeleteService, incluso si el servicio parece estar detenido.
Estoy hablando del código de la API de Windows aquí, pero quiero describir claramente lo que está sucediendo, por lo que esta secuencia puede conducir al error mencionado:
SC_HANDLE hScm = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hSvc = OpenService(hScm, L"Stub service", SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE);
SERVICE_STATUS ss;
ControlService(hSvc, SERVICE_CONTROL_STOP, &ss);
// ... wait for service to report its SERVICE_STOPPED state
DeleteService(hSvc);
CloseServiceHandle(hSvc);
hSvc = nullptr;
// any further calls to CreateService/DeleteService will fail
// if service process is still around
La razón por la que un proceso de servicio aún existe después de que ya ha informado su estado SERVICE_STOPPED no es sorprendente. Es un proceso regular, cuyo hilo principal está 'atascado' en su llamada alStartServiceCtrlDispatcher
API, por lo que primero reacciona a una acción de detener el control, pero luego tiene que ejecutar la secuencia de código restante.
Es desafortunado que SCM / OS no esté manejando esto adecuadamente para nosotros. Una solución programática es un poco simple y precisa: obtenga el identificador de proceso del ejecutable del servicio antes de detener el servicio, luego espere a que se señale este identificador.
Si se aborda el problema desde una perspectiva de administración del sistema, la solución también es esperar a que el proceso de servicio desaparezca por completo.