|
CNTService 类
当我创建 C 对象封装 Windows 函数时,我尝试为我封装的每个 Windows API 除了创建成员函数外,还做一些别的工作,我尝试让对象更容易使用,降低实现特定项目所需的代码行数。因此我的对象是基于“我想让这个对象做什么?”而不是“Windows 用这些 APIs 做什么?” 逆@风@者
CNTService 类包含一些用来解析命令行的成员函数,为了处理服务的安装和拆卸以及事件日志的记录,你得在派生类中重写一些虚拟函数来处理服务控制管理器的请求。下面我们将通过本文的例子服务实现来研究这些函数的使用。
如果你想创建尽可能简单的服务,只需要重写 CNTService::Run 即可,它是你编写代码实现具体服务任务的地方。你还需要实现 main 函数。如果服务需要实现一些初始化。如从注册表读取数据,还需重写 CNTService::OnInit。如果你要向服务发送命令消息 ,那么可以在服务中使用系统函数 ControlService,重写 CNTService::OnUserControl 来处理请求。
在例子应用程序中使用 CNTService
NTService 在 CMyService 类中实现了它的大多数功能,CMyService 由 CNTService 派生。 MyService.h 头文件如下:
// myservice.h
#include "ntservice.h"
class CMyService : public CNTService
{
public:
CMyService();
virtual BOOL OnInit();
virtual void Run();
virtual BOOL OnUserControl(DWORD dwOpcode);
void SaveStatus();
// Control parameters
int m_iStartParam;
int m_iIncParam;
// Current state
int m_iState;
};
正像你所看到的,CMyService 改写了 CNTService 的 OnInit、Run 和 OnUserControl。它还有一个函数叫 SaveStatus,这个函数被用于将数据写入注册表,那些成员变量用来保存当前状态。例子服务每隔一定的时间对一个整型变量进行增量处理。开始值和增量值都存在注册表的参数中。这样做并没有别的意图。只是为了简单示范。下面我们看看这个服务是如何实现的。
实现 main 函数
有了从 CNTService 派生的 CMyService,实现 main 函数很简单,请看 NTServApp.cpp 文件:
int main(int argc, char* argv[])
{
// 创建服务对象
CMyService MyService;
// 解析标准参数 (安装, 卸载, 版本等.)
if (!MyService.ParseStandardArgs(argc, argv)) {
// 未发现任何标准参数,所以启动服务,
// 取消下面 DebugBreak 代码行的注释,
// 当服务启动后进入调试器,
//DebugBreak();
MyService.StartService();
}
// 到这里,服务已经停止
return MyService.m_Status.dwWin32ExitCode;
}
这里代码不多,但执行后却发生了很多事情,让我们一步一步来看。首先,我们创建一个 MyService 类的实例。构造函数设置初始化状态和服务名字(MyService.cpp):
CMyService::CMyService():CNTService("NT Service Demonstration")
{
m_iStartParam = 0;
m_iIncParam = 1;
m_iState = m_iStartParam;
}
接着调用 ParseStandardArgs 检查命令行是否包含服务安装(-i)、卸载(-u)以及报告其版本号(-v)的请求。CNTService::ParseStandardArgs 分别调用 CNTService::IsInstalled,CNTService::Install 和 CNTService::Uninstall 来处理这些请求。如果没有可识别的命令行参数,则假设该服务控制管理器试图启动该服务并调用 StartService。该函数直到服务停止运行才返回。当你调试完代码,即可把用于调试的代码行注释掉或删除。
本文章更多内容:<<上一页 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 下一页>> |