// 重启指定服务 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) ", 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) ", 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) ", GetLastError()); break; } if ( ssp.dwCurrentState != SERVICE_STOPPED || SERVICE_STOP_PENDING == ssp.dwCurrentState) break; { DebugWrite(L"ERROR——————Service is already stopped. "); break; } // Send a stop code to the service. if ( !ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &ssp ) ) { DebugWrite(L"ERROR——————ControlService failed (%d) ", 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) ", GetLastError() ); break; } if ( ssp.dwCurrentState == SERVICE_STOPPED ) break; if ( GetTickCount() - dwStartTime > dwTimeout ) { DebugWrite(L"ERROR——————Wait timed out " ); 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) ", 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) ", 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) ", 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) ", GetLastError()); //printf("Service not started. "); //printf(" Current State: %d ", ssStatus.dwCurrentState); //printf(" Exit Code: %d ", ssStatus.dwWin32ExitCode); //printf(" Check Point: %d ", ssStatus.dwCheckPoint); //printf(" Wait Hint: %d ", ssStatus.dwWaitHint); } }while(false); if(NULL != schService) CloseServiceHandle(schService); if(NULL != schSCManager) CloseServiceHandle(schSCManager); }