一個類,用於全方位控制系統服務。
hServer.h
#ifndef __H_SERVER_H__
#define __H_SERVER_H__
#pragma once
#include <Windows.h>
class hServer {
public:
hServer (LPCTSTR servName);
~hServer ();
BOOL IsAutoRun ();
BOOL IsDemandRun ();
BOOL IsDisabled ();
BOOL SetAutoRun ();
BOOL SetDemandRun ();
BOOL SetDisabled ();
BOOL IsRunning ();
BOOL Start ();
BOOL Stop ();
private:
BOOL _ControlServices (BOOL (*callback)(SC_HANDLE));
BOOL _ControlServices (BOOL (*callback)(SC_HANDLE, SC_HANDLE));
LPTSTR h_servName;
};
#endif //__H_SERVER_H__
#include "hServer.h"
//#define _NO_COPY_
hServer::hServer (LPCTSTR servName) {
#ifdef _NO_COPY_
h_servName = const_cast<LPTSTR>(servName);
#else //_NO_COPY_
h_servName = new TCHAR [lstrlen (servName) + 1];
lstrcpy (h_servName, servName);
#endif //_NO_COPY_
}
hServer::~hServer () {
#ifndef _NO_COPY_
delete h_servName;
#endif //_NO_COPY_
}
BOOL hServer::IsAutoRun () {
return _ControlServices ([] (SC_HANDLE service) {
QUERY_SERVICE_CONFIG *qsc = (LPQUERY_SERVICE_CONFIG)new BYTE [8 * 1024];//查詢服務配置
DWORD d;
BOOL bRet = FALSE;
if (QueryServiceConfig (service, qsc, 8 * 1024, &d))
if (qsc->dwStartType <= 2)/*SERVICE_BOOT_START 0 SERVICE_SYSTEM_START 1 SERVICE_AUTO_START 2*/ bRet = TRUE;
delete qsc;
return bRet;
});
}
BOOL hServer::IsDemandRun () {
return _ControlServices ([] (SC_HANDLE service) {
QUERY_SERVICE_CONFIG *qsc = (LPQUERY_SERVICE_CONFIG)new BYTE [8 * 1024];//查詢服務配置
DWORD d;
BOOL bRet = FALSE;
if (QueryServiceConfig (service, qsc, 8 * 1024, &d))
if (qsc->dwStartType == SERVICE_DEMAND_START) bRet = TRUE;
delete qsc;
return bRet;
});
}
BOOL hServer::IsDisabled () {
return _ControlServices ([] (SC_HANDLE service) {
QUERY_SERVICE_CONFIG *qsc = (LPQUERY_SERVICE_CONFIG)new BYTE [8 * 1024];//查詢服務配置
DWORD d;
BOOL bRet = FALSE;
if (QueryServiceConfig (service, qsc, 8 * 1024, &d))
if (qsc->dwStartType == SERVICE_DISABLED) bRet = TRUE;
delete qsc;
return bRet;
});
}
BOOL hServer::SetAutoRun () {
return _ControlServices ([] (SC_HANDLE scm, SC_HANDLE service) {
SC_LOCK sclLock = LockServiceDatabase (scm);
BOOL bRet = ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (sclLock) UnlockServiceDatabase (sclLock);
return bRet;
});
}
BOOL hServer::SetDemandRun () {
return _ControlServices ([] (SC_HANDLE scm, SC_HANDLE service) {
SC_LOCK sclLock = LockServiceDatabase (scm);
BOOL bRet = ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (sclLock) UnlockServiceDatabase (sclLock);
return bRet;
});
}
BOOL hServer::SetDisabled () {
return _ControlServices ([] (SC_HANDLE scm, SC_HANDLE service) {
SC_LOCK sclLock = LockServiceDatabase (scm);
BOOL bRet = ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (sclLock) UnlockServiceDatabase (sclLock);
return bRet;
});
}
BOOL hServer::IsRunning () {
return _ControlServices ([] (SC_HANDLE service) {
SERVICE_STATUS status;//查詢服務狀態
if (QueryServiceStatus (service, &status))
return (BOOL) (status.dwCurrentState == SERVICE_RUNNING || status.dwCurrentState == SERVICE_START_PENDING);
return FALSE;
});
}
BOOL hServer::Start () {
return _ControlServices ([] (SC_HANDLE service) {
SERVICE_STATUS status;//查詢服務狀態
if (QueryServiceStatus (service, &status)) {
if (status.dwCurrentState == SERVICE_RUNNING) return TRUE;
}
return StartService (service, NULL, NULL);
});
}
BOOL hServer::Stop () {
return _ControlServices ([] (SC_HANDLE service) {
SERVICE_STATUS status;//查詢服務狀態
if (QueryServiceStatus (service, &status)) {
if (status.dwCurrentState == SERVICE_STOPPED) return TRUE;
}
return ControlService (service, SERVICE_CONTROL_STOP, &status);
});
}
BOOL hServer::_ControlServices (BOOL (*callback)(SC_HANDLE)) {
SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!scm) return FALSE;
SC_HANDLE service = OpenService (scm, h_servName, SERVICE_ALL_ACCESS);
if (!service) {
CloseServiceHandle (scm);
return FALSE;
}
BOOL bRet = callback (service);
CloseServiceHandle (service);
CloseServiceHandle (scm);
return bRet;
}
BOOL hServer::_ControlServices (BOOL (*callback)(SC_HANDLE, SC_HANDLE)) {
SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!scm) return FALSE;
SC_HANDLE service = OpenService (scm, h_servName, SERVICE_ALL_ACCESS);
if (!service) {
CloseServiceHandle (scm);
return FALSE;
}
BOOL bRet = callback (scm, service);
CloseServiceHandle (service);
CloseServiceHandle (scm);
return bRet;
}
函數名比較簡單,大家都看得懂,不做過多的註釋。另外爲了節省代碼量,全篇代碼均使用了函數式編程。所以請用高版本vs編譯。。。
另外,hServer.cpp文件裏面有一個宏,_NO_COPY_,如果定義了這個宏,類將不會單獨分配一串內存用於存儲服務名稱。如果服務名稱在堆中爲常量,完全可以將這行代碼取消註釋。由於不涉及服務名稱更改(需要控制多個服務請自行實例化多個對象),所以直接使用最簡潔的C STRING。