Parece que nas versões do Windows posteriores ao Windows 7 (não verificadas, mas pela experiência mais recente do Windows Server 2012 R2), o Service Control Manager (SCM) é mais rigoroso.
Enquanto no Windows 7 ele gera outro processo, agora está verificando se o processo do serviço ainda está por aí e pode retornar ERROR_SERVICE_MARKED_FOR_DELETE (1072) para qualquer chamada subsequente ao CreateService / DeleteService, mesmo que o serviço pareça estar parado.
Estou falando do código da API do Windows aqui, mas quero descrever claramente o que está acontecendo, portanto, essa sequência pode levar ao erro 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
A razão pela qual um processo de serviço ainda existe após já ter relatado seu estado SERVICE_STOPPED não é surpreendente. É um processo regular, cuja thread principal está 'presa' em sua chamada para oStartServiceCtrlDispatcher
API, para que ele reaja primeiro a uma ação de controle de parada, mas depois execute sua sequência de código restante.
É meio lamentável que o SCM / OS não esteja lidando com isso adequadamente para nós. Uma solução programática é meio simples e precisa: obtenha o identificador de processo do executável do serviço antes de interromper o serviço e aguarde até que esse identificador seja sinalizado.
Ao abordar o problema da perspectiva da administração do sistema, a solução é também aguardar o processo de serviço desaparecer completamente.