Search code examples
winapiserviceatlshutdown

Windows service shut down


I use VS6 and ATL with CServiceModule to implement a custom windows service. In case of a fatal error service should shut itself down. Since CServiceModule is available via _Module variable in all files I thought of something like this to cause CServiceModule::Run to stop pumping messages and shut itself down

PostThreadMessage(_Module.dwThreadID, WM_QUIT, 0, 0);

Is this correct or you have better idea ?


Solution

  • For self shutdown you send command to Service Manager. Try this sample :

    
    BOOL StopServiceCmd ( const char * szServiceName )
    { 
        SC_HANDLE schService; 
        SC_HANDLE schSCManager; 
        SERVICE_STATUS ssStatus;       // current status of the service 
        BOOL bRet;
        int iCont=0;
    
        schSCManager = OpenSCManager( 
            NULL, // machine (NULL == local) 
            NULL, // database (NULL == default) 
            SC_MANAGER_ALL_ACCESS // access required 
            ); 
        if ( schSCManager ) 
        { 
            schService = OpenService(schSCManager, szServiceName, SERVICE_ALL_ACCESS); 
    
            if (schService) 
            { 
                // try to stop the service 
                if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) ) 
                { 
                    Sleep( 1000 ); 
    
                    while( QueryServiceStatus( schService, &ssStatus ) ) 
                    { 
                        iCont++;
                        if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) 
                        { 
                            Sleep( 1000 ); 
                            if ( iCont > 4 ) break;
                        } 
                        else 
                            break; 
                    } 
    
                    if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) 
                        bRet = TRUE; 
                    else 
                        bRet = FALSE; 
                } 
    
                CloseServiceHandle(schService); 
            } 
            else 
                bRet = FALSE; 
    
            CloseServiceHandle(schSCManager); 
        } 
        else 
            bRet = FALSE;
    
        return bRet;
    }