日常开发中,会遇到改变某个服务的参数,并进行重启(例如Redis断电恢复机制)
需要程序拥有UAC权限,并且调用如下API才能对windows服务进行重启:
cpp
#include "windows.h"
#pragma comment(lib, "advapi32.lib")
bool ConfigCenter::ReStartServiceByName(std::string strDestServiceName)
{
bool bServiceStatus = FALSE;
SC_HANDLE schSCManager = nullptr ;
SC_HANDLE schService = nullptr ;
DWORD dwBytesNeeded = 0 ;
SERVICE_STATUS_PROCESS ssStatus;
char szSvcName[MAX_PATH] = {0};
memcpy_s(szSvcName,MAX_PATH,strDestServiceName.c_str(),strDestServiceName.length());
//! 获取一个服务控制管理器数据库的句柄
schSCManager = OpenSCManager(
nullptr , // local computer
nullptr , // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if(schSCManager == nullptr) {
qDebug() << "OpenSCManager fail" << endl;
return bServiceStatus;
}
//! 获取该服务在服务控制管理器数据库中的句柄
schService = OpenServiceA(
schSCManager, // SCM database
szSvcName, // name of service
SERVICE_ALL_ACCESS/* | DELETE*/); // full access
if(schService == nullptr) {
CloseServiceHandle(schSCManager);
qDebug() << "Get a handle to the service fail" << endl;
return bServiceStatus;
}
//! 查询该服务的当前状态
if(!QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // information level
(LPBYTE) &ssStatus, // address of structure
sizeof (SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // size needed if buffer is too small
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
qDebug() << "QueryServiceStatusEx fail" << endl;
return bServiceStatus;
}
else
{
switch (ssStatus.dwCurrentState)
{
case SERVICE_STOPPED:
case SERVICE_STOP_PENDING:
qDebug() << szSvcName << " Service status is Stop" << endl;
break ;
case SERVICE_PAUSED:
case SERVICE_PAUSE_PENDING:
qDebug() << szSvcName << " Service status is Pause" << endl;
break ;
case SERVICE_CONTINUE_PENDING:
case SERVICE_RUNNING:
case SERVICE_START_PENDING:
qDebug() << szSvcName << " Service status is Running" << endl;
bServiceStatus = TRUE;
break ;
}
}
//! 停止该服务
if(bServiceStatus == TRUE) {
SERVICE_STATUS status;
if (!ControlService(schService, SERVICE_CONTROL_STOP, &status)) {
qDebug() << "ControlService failed with error:" << GetLastError();
return !bServiceStatus;
}
}
//! 启动该服务
StartService(schService,0,nullptr);
Sleep(500);
//! 获得服务的当前状态
QueryServiceStatusEx(schService,SC_STATUS_PROCESS_INFO,(LPBYTE) &ssStatus,sizeof (SERVICE_STATUS_PROCESS),&dwBytesNeeded );
if (SERVICE_RUNNING == ssStatus.dwCurrentState)
{
bServiceStatus = TRUE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return bServiceStatus;
}