简单的C++代码编写windows服务

2017-01-13 08:17:46来源:CSDN作者:sf0407人点击

第七城市

继上一章flex通信之后,接下来需要为程序集成到windows服务做准备了,首先需要学习如何编写一个windows服务。

一,windows服务的代码如下:

#include "stdafx.h"#include "resource.h"using namespace std;//服务的状态,和服务停止事件SERVICE_STATUS			serviceStatus;SERVICE_STATUS_HANDLE	serviceStatusHandle;HANDLE					serviceStopEvent;//服务的控制void WINAPI ServiceMain(DWORD, LPTSTR*);void WINAPI ServiceInit(DWORD, LPTSTR*);void WINAPI ServiceContrl(DWORD optionCode);//记录服务的状态void ReportServiceStatus(DWORD, DWORD, DWORD);//服务的安装与卸载,服务的状态BOOL Install();BOOL Uninstall();//属性与对象TCHAR serviceName[256];TCHAR serviceDisplayName[256];TCHAR serviceMainClassPath[256];TCHAR serviceDescription[256];int _tmain(int argc, _TCHAR* argv[]) {	outLog("main start");	cout << "main start" << endl;	TCHAR* actionArg = argv[1];	//如果传入了参数"install",则安装服务,另外服务能够被SCM控制	if (lstrcmpi(actionArg, _T("install")) == 0) {		Install();	}	//输入的参数为卸载时	else if (lstrcmpi(actionArg, _T("uninstall")) == 0) {		Uninstall();	}	//服务的数组信息	SERVICE_TABLE_ENTRY dispatchTable[] = {		{ serviceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain }	};	//启动服务控制方法启动服务,判断启动失败时	if (!StartServiceCtrlDispatcher(dispatchTable)) {		outLog("StartServiceCtrlDispatcher error", GetLastError());		//Uninstall();		return -1;	}	else {		outLog("StartServiceCtrlDispatcher successfully");	}	return 0;}/**安装服务**/BOOL Install() {	//控制器	SC_HANDLE schSCManager;	SC_HANDLE schService;	TCHAR servicePath[MAX_PATH];	//服务描述	SERVICE_DESCRIPTION serviceDesc;	//加载多语言字段	LoadString(NULL, IDS_SERVICENAME, serviceName, sizeof(serviceName) / sizeof(TCHAR));	LoadString(NULL, IDS_SERVICEDISPLAYNAME, serviceDisplayName, sizeof(serviceDisplayName) / sizeof(TCHAR));	LoadString(NULL, IDS_SERVICEMAINCLIASSPATH, serviceMainClassPath, sizeof(serviceMainClassPath) / sizeof(TCHAR));	LoadString(NULL, IDS_SERVICEDESCRIPTION, serviceDescription, sizeof(serviceDescription) / sizeof(TCHAR));	//判断文件是否可访问	if (!GetModuleFileName(NULL, servicePath, MAX_PATH)) {		cout << "Cannot install service" << endl;		return false;	}	//打开服务控制管理器	schSCManager = OpenSCManager(		NULL,							//本地电脑		NULL,							//服务激活的位置		SC_MANAGER_ALL_ACCESS);			//全部动作允许	if (NULL == schSCManager) {		cout << "OpenSCManager failed" << endl;		return false;	}	//创建服务	schService = CreateService(		schSCManager,					//服务管理控制器对象		serviceName,					//名称		serviceDisplayName,				//显示的名称		SERVICE_ALL_ACCESS,				//访问请求		SERVICE_WIN32_OWN_PROCESS,		//服务类型		SERVICE_AUTO_START,				//启动类型  自动 SERVICE_AUTO_START,手动 SERVICE_DEMAND_START,禁止 SERVICE_DISABLED		SERVICE_ERROR_NORMAL,			//错误类型		servicePath,					//服务路径		NULL,							//不导入额外的组		NULL,							//不标记权限		NULL,							//不依赖		NULL,							//本地账号		NULL);							//无密码	if (NULL == schService) {		outLog("CreateService failed", GetLastError());		CloseServiceHandle(schSCManager);		return false;	}	else {		outLog("Servcie install successfully");	}	//添加服务描述	serviceDesc.lpDescription = serviceDescription;	boolean changeRes = ChangeServiceConfig2(		schService,							//服务控制器		SERVICE_CONFIG_DESCRIPTION,			//改变:描述		&serviceDesc);						//新的描述	if (!changeRes) {		outLog("ChangeServiceConfig2 DESCRIPTION failed");	}	else {		outLog("ChangeServiceConfig2 DESCRIPTION successfully");	}	//启动服务,成功则关闭控制器	boolean startServiceRes = StartService(schService, 0, NULL);	if (!startServiceRes) {		outLog("StartService failed", GetLastError());		//关闭获得的控制器		CloseServiceHandle(schService);		CloseServiceHandle(schSCManager);	}	else {		outLog("StartService successfully");	}	//关闭获得的控制器	CloseServiceHandle(schService);	CloseServiceHandle(schSCManager);	return true;}/**卸载服务**/BOOL Uninstall() {	SC_HANDLE schSCManager;	SC_HANDLE schService;	//打开服务控制管理器	schSCManager = OpenSCManager(		NULL,							//本地电脑		NULL,							//服务激活的位置		SC_MANAGER_ALL_ACCESS);			//全部动作允许	if (NULL == schSCManager) {		outLog("Uninstall OpenSCManager failed");		return false;	}	//打开服务	schService = OpenService(		schSCManager,					//服务管理控制器对象		serviceName,					//名称		SERVICE_STOP | DELETE);	if (NULL == schService) {		CloseServiceHandle(schSCManager);		outLog("Uninstall OpenService failed");		return false;	}	//停止服务	ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus);	//删除服务	BOOL deleteServcie = DeleteService(schService);	//关闭控制器	CloseServiceHandle(schService);	CloseServiceHandle(schSCManager);	if (deleteServcie) {		return true;	}	outLog("Service could not be deleted");	return false;}/**服务主方法,服务的主要逻辑**/void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {	outLog("ServiceMain start");	//给服务注册控制器	serviceStatusHandle = RegisterServiceCtrlHandler(		serviceName,		ServiceContrl);	//判断是否注册成功	if (!serviceStatusHandle) {		outLog("RegisterServiceCtrlHandler failed");		return;	}	//重制服务的状态码 SERVICE_STATUS	serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;	serviceStatus.dwServiceSpecificExitCode = 0;	//记录服务状态到服务管理器上	ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000);	//初始化	ServiceInit(dwArgc, lpszArgv);}/**初始化服务dwArgc - 传入的数组长度lpszArgv - 传入的数组**/void WINAPI ServiceInit(DWORD dwArgc, LPTSTR *lpszArgv) {	//定义和初始化所需的参数,保证SERVICE_START_PENDING能够访问	//ReportSvcStatus().如果初始化失败则改变服务状态为SERVICE_STOPPED.	//创建一个事件,当接收到停止代码时触发动作	serviceStopEvent = CreateEvent(		NULL,										//默认的安全参数		TRUE,										//手工重制Event		FALSE,										//初始为无信号		NULL);										//没有名称	if (NULL == serviceStopEvent) {		ReportServiceStatus(SERVICE_STOP, NO_ERROR, 0);		return;	}	//初始化完后记录运行状态	ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0);	//当服务停止时	while (1) {		//检查服务是否停止(即停止事件是否被触发)		WaitForSingleObject(serviceStopEvent, INFINITE);		ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);		return;	}}/**设置当前服务状态并且记录到服务管理器中**/void ReportServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) {	static DWORD dwCheckPoint = 1;	//初始化SERVICE_STATUS结构体	serviceStatus.dwCurrentState = dwCurrentState;			//当前状态		serviceStatus.dwWin32ExitCode = dwWin32ExitCode;		//错误码	serviceStatus.dwWaitHint = dwWaitHint;				//等待时间ms	//指定了控制请求是否通知服务,0为不通知	if (dwCurrentState == SERVICE_START_PENDING) {		serviceStatus.dwControlsAccepted = 0;	}	else {		serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;	}	//设置等待时间,dwWaitHint为超时时间,dwCheckPoint报告服务状态的改变次数	if ((dwCurrentState == SERVICE_RUNNING) ||		(dwCurrentState == SERVICE_STOPPED)) {		serviceStatus.dwCheckPoint = 0;	}	else {		serviceStatus.dwCheckPoint = dwCheckPoint++;	}	//记录服务的状态到任务资源管理器	SetServiceStatus(serviceStatusHandle, &serviceStatus);}/**访问服务管理器改变服务的状态时会访问此方法**/void WINAPI ServiceContrl(DWORD dwCtrl) {	outLog("ServiceContrl:", dwCtrl);	//请求的控制代码	switch (dwCtrl) {	case SERVICE_CONTROL_STOP://停止服务		ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);		//发送服务停止信号		SetEvent(serviceStopEvent);		ReportServiceStatus(serviceStatus.dwCurrentState, NO_ERROR, 0);		break;	case SERVICE_CONTROL_INTERROGATE://询问		break;	case SERVICE_CONTROL_PAUSE:		break;	case SERVICE_CONTROL_CONTINUE:		break;	case SERVICE_CONTROL_SHUTDOWN:		break;	default:		outLog("error ServiceContrl code", dwCtrl);		break;	}}
window服务需要展示一些服务的信息,为了改动方便,引入资源文件:LoadJVMDemo.rc

二,资源文件包含一个String Table资源和Version资源


String Table资源内容为:


对应的生成的resource.h文件内容为:

//{{NO_DEPENDENCIES}}// Microsoft Visual C++ 生成的包含文件。// 供 LoadJVMDemo.rc 使用//#define IDS_SERVICENAME                 101#define IDS_SERVICEDISPLAYNAME          102#define IDS_SERVICEMAINCLIASSPATH       103#define IDS_SERVICEDESCRIPTION          104// Next default values for new objects// #ifdef APSTUDIO_INVOKED#ifndef APSTUDIO_READONLY_SYMBOLS#define _APS_NEXT_RESOURCE_VALUE        102#define _APS_NEXT_COMMAND_VALUE         40001#define _APS_NEXT_CONTROL_VALUE         1001#define _APS_NEXT_SYMED_VALUE           101#endif#endif
在cmd中安装


在系统服务中可以看到安装成功


在系统盘路径:C:/Windows/System32/LoadJVMDemoC.log下可以看到日志


在系统服务中将服务状态改成“停止”,然后再改成“启动”,可以看到日志如下


若以上日志正常打印,说明服务已经成功安装,并正常运行了。

三,删除服务

先停止服务,用管理员方式打开cmd,输入:sc stop ServiceDemo


接着输入:sc delete ServiceDemo


在系统服务中刷新可以看到之前的服务已经被删除了。



以上为简单的C++代码编写windows服务学习。

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台