Win32 服務控制

一個類,用於全方位控制系統服務。

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__


hServer.cpp
#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。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章