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

来源:互联网 发布:手机游戏无法连接网络 编辑:程序博客网 时间:2024/05/18 00:42

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

一,windows服务的代码如下:

#include "stdafx.h"#include "resource.h"using namespace std;//服务的状态,和服务停止事件SERVICE_STATUSserviceStatus;SERVICE_STATUS_HANDLEserviceStatusHandle;HANDLEserviceStopEvent;//服务的控制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_DISABLEDSERVICE_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_STATUSserviceStatus.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,//手工重制EventFALSE,//初始为无信号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服务学习。

0 0
原创粉丝点击