Windows下重启指定名称的服务

// 重启指定服务
void CPSSDPrinterCtrlPlug::RestartService(const wchar_t* nswServiceName)
{
    SC_HANDLE schSCManager = NULL;
    SC_HANDLE schService = NULL;

    do
    {
        // -------------------------------------------------------------------------------------------------------------------------
        // open

        // Get a handle to the SCM database. 
        schSCManager = OpenSCManager(
            NULL,                    // local computer
            NULL,                    // ServicesActive database 
            SC_MANAGER_ALL_ACCESS);  // full access rights 
        if (NULL == schSCManager) 
        {
            DebugWrite(L"ERROR——————OpenSCManager failed (%d)\n", GetLastError());
            break;
        }

        // Get a handle to the service.
        schService = OpenService( 
            schSCManager,            // SCM database 
            nswServiceName,               // name of service 
            SERVICE_CHANGE_CONFIG);  // need change config access 
        if (schService == NULL)
        { 
            DebugWrite(L"ERROR——————OpenService failed (%d)\n", GetLastError()); 
            break;
        }    

        // -------------------------------------------------------------------------------------------------------------------------
        // stop

        // Make sure the service is not already stopped.
        DWORD dwBytesNeeded;
        SERVICE_STATUS_PROCESS ssp;
        if ( !QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS),
            &dwBytesNeeded ) )
        {
            DebugWrite(L"ERROR——————QueryServiceStatusEx failed (%d)\n", GetLastError()); 
            break;
        }
        if ( ssp.dwCurrentState != SERVICE_STOPPED || SERVICE_STOP_PENDING == ssp.dwCurrentState)
            break;
        {
            DebugWrite(L"ERROR——————Service is already stopped.\n");
            break;
        }
        
        // Send a stop code to the service.
        if ( !ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &ssp ) )
        {
            DebugWrite(L"ERROR——————ControlService failed (%d)\n", GetLastError() );
            break;
        }

        // Wait for the service to stop.
        DWORD dwStartTime = GetTickCount();
        DWORD dwTimeout = 30000; // 30-second time-out
        while ( ssp.dwCurrentState != SERVICE_STOPPED ) 
        {
            Sleep( ssp.dwWaitHint );
            if ( !QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) )
            {
                DebugWrite(L"ERROR——————QueryServiceStatusEx failed (%d)\n", GetLastError() );
                break;
            }

            if ( ssp.dwCurrentState == SERVICE_STOPPED )
                break;

            if ( GetTickCount() - dwStartTime > dwTimeout )
            {
                DebugWrite(L"ERROR——————Wait timed out\n" );
                break;
            }
        }
        
        if(ssp.dwCurrentState != SERVICE_STOPPED)
            break;

        // -------------------------------------------------------------------------------------------------------------------------
        // start

        // Attempt to start the service.
        if (!StartService(schService,  // handle to service 
            0,           // number of arguments 
            NULL) )      // no arguments 
        {
            DebugWrite(L"ERROR——————StartService failed (%d)\n", GetLastError());
            break;
        }

        // Check the status until the service is no longer start pending. 
        SERVICE_STATUS_PROCESS ssStatus; 
        if (!QueryServiceStatusEx( 
            schService,             // handle to service 
            SC_STATUS_PROCESS_INFO, // info level
            (LPBYTE) &ssStatus,             // address of structure
            sizeof(SERVICE_STATUS_PROCESS), // size of structure
            &dwBytesNeeded ) )              // if buffer too small
        {
            DebugWrite(L"ERROR——————QueryServiceStatusEx failed (%d)\n", GetLastError()); 
            break; 
        }

        // Save the tick count and initial checkpoint.
        dwStartTime = GetTickCount();
        DWORD dwWaitTime;
        DWORD dwOldCheckPoint = ssStatus.dwCheckPoint;
        while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
        { 
            // Do not wait longer than the wait hint. A good interval is 
            // one-tenth the wait hint, but no less than 1 second and no 
            // more than 10 seconds. 
            dwWaitTime = ssStatus.dwWaitHint / 10;

            if( dwWaitTime < 1000 )
                dwWaitTime = 1000;
            else if ( dwWaitTime > 10000 )
                dwWaitTime = 10000;
            Sleep( dwWaitTime );

            // Check the status again. 
            if (!QueryServiceStatusEx( 
                schService,             // handle to service 
                SC_STATUS_PROCESS_INFO, // info level
                (LPBYTE) &ssStatus,             // address of structure
                sizeof(SERVICE_STATUS_PROCESS), // size of structure
                &dwBytesNeeded ) )              // if buffer too small
            {
                DebugWrite(L"ERROR——————QueryServiceStatusEx failed (%d)\n", GetLastError());
                break; 
            }

            if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
            {
                // The service is making progress.
                dwStartTime = GetTickCount();
                dwOldCheckPoint = ssStatus.dwCheckPoint;
            }
            else
            {
                if(GetTickCount()- dwStartTime > ssStatus.dwWaitHint)
                {
                    // No progress made within the wait hint.
                    break;
                }
            }
        } 

        // Determine whether the service is running
        if (ssStatus.dwCurrentState != SERVICE_RUNNING) 
        { 
            DebugWrite(L"ERROR——————start spooler failed (%d)\n", GetLastError());
            //printf("Service not started. \n");
            //printf("  Current State: %d\n", ssStatus.dwCurrentState); 
            //printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode); 
            //printf("  Check Point: %d\n", ssStatus.dwCheckPoint); 
            //printf("  Wait Hint: %d\n", ssStatus.dwWaitHint); 
        } 

    }while(false);
    if(NULL != schService)
        CloseServiceHandle(schService); 
    if(NULL != schSCManager)
        CloseServiceHandle(schSCManager);
}
posted on 2014-09-11 17:15  好好单调  阅读(535)  评论(0编辑  收藏  举报