概述
继上一章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:WindowsSystem32LoadJVMDemoC.log下可以看到日志
在系统服务中将服务状态改成“停止”,然后再改成“启动”,可以看到日志如下
若以上日志正常打印,说明服务已经成功安装,并正常运行了。
三,删除服务
先停止服务,用管理员方式打开cmd,输入:sc stop ServiceDemo
接着输入:sc delete ServiceDemo
在系统服务中刷新可以看到之前的服务已经被删除了。
以上为简单的C++代码编写windows服务学习。
最后
以上就是忧虑御姐为你收集整理的简单的C++代码编写windows服务的全部内容,希望文章能够帮你解决简单的C++代码编写windows服务所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复