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);

}

你可能感兴趣的:(windows)