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。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-21 22:14:03

Win32 服务控制的相关文章

Windows服务程序的原理及实现(服务分为WIN32服务和系统服务)

今天给大家讲下怎样做一个服务程序...本来是想详细讲的,不过写着写着累得要命..很多 地方就没详细...不过代码我加了点注...如果还有一些不明白的自己查下MSDN......便宜 环境,,VC++6.0...代码有俩段,一段是服务程序的..另一段是安装服务程序的...这个程序 的功能是开机发出滴滴声....安装成功后自己点启动...下次开机就自动起动了.... load.exe的实现是比较简单,本来想弄个汇编版本...不过真的累...就算了..这里一个服 务的基本框架就完成了...剩下的只是添

Linux安装及服务控制

一.  版本 Red Hat 企业版   Red Hat Enterprise Linux (简称RHEL) http://www.redhat.com Fedora社区版 由Red Hat资助的社区维护,定位于个人桌面用户 http://fedoraproject.org CentOS社区版 Community Enterprise Operating System(社区企业操作系统) http://www.centos.org 二.  安装步骤 插入RHEL6安装光盘,引导安装程序 设置主机

利用BashShell编写Nginx服务控制脚本

使用源码包安装的Nginx没办法使用"service nginx start"或"/etc/init.d/nginx start"进行操作和控制,所以写了以下的服务控制脚本. 可以使用的选项有: start  启动 stop  停止 reload 重载 restart  重启 status   状态 test 检查配置文件 1.创建脚本文件并添加执行权限 # touch /etc/init.d/nginx # chmod +x /etc/init.d/nginx 2

Red Hat Linux 安装及服务控制

1.1安装 Red Hat Linux 1. 插入RHEL 6 安装光盘并引导安装程序 根据提示选择不同的安装模式,这里选择“Install or upgrade an existing system”“,即“安装或升级现有的系统”.(其选项是在有显卡驱动程序的情况下安装-图形安装) 2.检测安装光盘的完整性 提醒用户检测光盘安装的完整性,光盘检测需要花费较长的时间,可以按下”Tab键“跳过检测过程. 3. 配置安装程序 (1)首先显示的是安装程序的欢迎界面,单击“Next”按钮继续. (2)选

linux引导过程和服务控制

引导过程和服务控制 要求: ? 设置Linux系统每次开机后自动进入字符模式界面. 步骤: 编辑/etc/inittab文件,将默认运行级别修改为3.如图所示: ? 使用ntsysv工具同时调整2.3.4.5运行级别中的服务状态,关闭下列服务:anacron.atd.avahi-daemon.Bluetooth.cups.firstboot.hidd.hplip.ip6tables.iptables.isdn.mcstrans.mdmonitor.nfslock.pcscd.portmap.re

linux的引导过程和服务控制

引导过程和服务控制 要求: ? 设置Linux系统每次开机后自动进入字符模式界面. 步骤: 编辑/etc/inittab文件,将默认运行级别修改为3.如图所示: ? 使用ntsysv工具同时调整2.3.4.5运行级别中的服务状态,关闭下列服务:anacron.atd.avahi-daemon.Bluetooth.cups.firstboot.hidd.hplip.ip6tables.iptables.isdn.mcstrans.mdmonitor.nfslock.pcscd.portmap.re

DHCP和TFTP配置以及CentOS 7上的服务控制

一.DHCP DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)用来给局域网的主机动态配置网络参数(IP地址.子网掩码.网关等),采用client/server架构 1.工作原理 ①DHCP Client以广播的方式发出DHCP Discover报文. ②广播域内所有的DHCP Server都能够接收到DHCP Client发送的DHCP Discover报文并且都会向其响应一个DHCP Offer报文. DHCP Offer报文中除了提供给DH

运维经验分享(七)-- Linux Shell之ChatterServer服务控制脚本第三次优化

运维经验分享作为一个专题,目前共7篇文章 <运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本> <运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化> <运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行Shell脚本的问题(一)> <运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析> <运维经验分享(五)-- 改进的java进程管

运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析

运维经验分享作为一个专题,目前共7篇文章 <运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本> <运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化> <运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行Shell脚本的问题(一)> <运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析> <运维经验分享(五)-- 改进的java进程管