ACE_NT_Service(WINDOWS

ACE_NT_Service(WINDOWS

ACE_NT_Service(WINDOWS)
本人的观点,SERVICE就是WINDOWS版的DAEMON。ACE_NT_Service通过包装一整套WINDOWS提供的SERVICE API定义了一个控制NT SERVICE的接口。应用程序继承该接口就可以实现和UNIX上DAEMON相似的功能。下面先简单描述WINDOWSSERVICE程序框架,再详细描述类ACE_NT_Service对WINDOWS SERVICE程序框架的包装。

WINDOWS SERVICE
一个完整的NT SERVICE程序应该包含以下四部分:
1.控制台应用程序的main函数
2.SERVICE入口函数ServiceMain
3.SERVICE CONTROL HANDLER,SCM利用该函数和SERVICE通信并控制程序的起停。
4.SERVICE安装和卸载器

ServiceMain和Service Control Handler
首先我们来讨论ServiceMain和Service Control Handler。WINDOWS规定每个SERVICE都拥有自己独立的ServiceMain以及Service Control Handler函数。主程序调用StartServiceCtrlDispatcher时,WINDOWS为每个SERVICE创建一个线程,并且在新线程中运行ServiceMain函数。SCM利用Service Control Handler函数和SERVICE程序通信,用户执行start,stop,pause以及continue等操作时,SCM通过Service Control Handler函数来控制SERVICE的行为。Service Control Handler函数基本上会包含一个switch语句来处理每种情况。

安装/卸载SERVICE
WINDOWS提供一些API来安装/卸载SERVICE,这样我们就可以不使用注册函数就能在系统中注册这些节点。这些API分别是CreateService和DeleteService。要安装SERVICE,需要先利用函数OpenSCManager打开SCM数据库,接着利用SERVICE的二进制文件路径调用CreateService,在调用CreateService时需要为SERVICE指定名称,原因是使用DeleteService删除服务时需要利用该标识。

ACE_NT_Service
查看ACE源码,其中和类 ACE_NT_Service实现密切相关的的文件有NT_Service.cpp、NT_Service.h、NT_Service.i。

ACE_NT_Service中的ServiceMain和Service Control Handler
ServiceMain和Service Control Handler定义具有固定模式,ACE_NT_Service提供宏#define ACE_NT_SERVICE_DEFINE(SVCNAME, SVCCLASS, SVCDESC)用于简化定义。具体的宏定义可以参考ACE代码,这里不再列出,这里只分析相关的类ACE_NT_Service的成员函数handle_control,init,open,wait和fini。函数handle_control被用于响应SERVICE DISPATCHER请求,其必须和SVC函数交互以影响请求控制操作。缺省实现包括SERVICE_CONTROL_STOP,SERVICE_CONTROL_PAUSE,SERVICE_CONTROL_CONTINUE,SERVICE_CONTROL_INTERROGATE,SERVICE_CONTROL_SHUTDOWN。

函数handle_control的部分关键代码解析
/* 调用stop_requested响应关闭操作 */
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
this->stop_requested (control_code);
break;
/* 调用pause_requested响应挂起操作 */
case SERVICE_CONTROL_PAUSE:
this->pause_requested (control_code);
break;
/* 调用continue_requested响应挂起后启动操作 */
case SERVICE_CONTROL_CONTINUE:
this->continue_requested (control_code);
break;
/* 调用interrogate_requested报告当前状态*/
case SERVICE_CONTROL_INTERROGATE:
this->interrogate_requested (control_code);
break;

函数open 的部分关键代码解析
/* 报告状态 */
this->report_status (SERVICE_START_PENDING, 0);
/* 执行用户代码 */
int svc_return = this->svc ();

函数fini 的部分关键代码解析
/* 报告状态 */
return this->report_status (SERVICE_STOPPED, 0);

函数stop_requested的部分关键代码解析
/* 报告状态 */
this->report_status (SERVICE_STOP_PENDING);

函数pause_requested的部分关键代码解析
/* 报告状态 */
this->report_status (SERVICE_PAUSE_PENDING);
/* 挂起*/
this->suspend ();
/* 报告状态 */
this->report_status (SERVICE_PAUSED);

函数continue_requested的部分关键代码解析
/* 报告状态 */
this->report_status (SERVICE_CONTINUE_PENDING);
/* 恢复*/
this->resume ();
/* 报告状态 */
this->report_status (SERVICE_RUNNING);

函数interrogate_requested的部分关键代码解析
/* 报告状态 */
this->report_status (0);
安装/卸载SERVICE
ACE_NT_Service定义两个成员函数Insert,remove来安装(卸载)SERVICE。它们分别在内部调用WINDOWS API——CreateService以及DeleteService。

Insert函数的部分关键代码解析

/* 打开和host()上SCManager的通信 */
SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (),……);
/* 以名称name() 创建服务 */
SC_HANDLE sh = ACE_TEXT_CreateService (sc_mgr,this->name (),this->desc (),
SERVICE_ALL_ACCESS,this->svc_status_.dwServiceType,start_type,
error_control,exe_path,……);
/* 关闭和SCManager的通信 */
CloseServiceHandle (sc_mgr);
/* 关闭服务句柄,重新写入新句柄 */
if (this->svc_sc_handle_ != 0)
CloseServiceHandle (this->svc_sc_handle_);
this->svc_sc_handle_ = sh;

Remove函数部分关键代码解析

/* 从SCM中删除insert创建的服务句柄 */
if (DeleteService (this->svc_sc_handle()) == 0
&& GetLastError () != ERROR_SERVICE_MARKED_FOR_DELETE)
控制SERVICE
ACE_NT_Service定义成员函数start_svc, stop_svc, pause_svc, continue_svc分别用于启动、停止、挂起和继续服务。
start_svc函数的部分关键代码解析

/* 启动服务 */
if (!ACE_TEXT_StartService (svc, argc, argv))
this->wait_for_service_state (SERVICE_RUNNING, wait_time);

stop_svc函数的部分关键代码解析

/* 关闭服务 */
if (!ControlService (svc, SERVICE_CONTROL_STOP, &this->svc_status_))
this->wait_for_service_state (SERVICE_STOPPED, wait_time);

pause_svc函数的部分关键代码解析

/* 吊起服务 */
if (!ControlService (svc, SERVICE_CONTROL_PAUSE,&this->svc_status_))
this->wait_for_service_state (SERVICE_PAUSED,wait_time);

continue_svc函数的部分关键代码解析

/* 将挂起业务重新启动 */
if (!ControlService (svc,SERVICE_CONTROL_CONTINUE,&this->svc_status_))
this->wait_for_service_state (SERVICE_RUNNING,wait_time);

一些辅助函数
svc_sc_handle部份关键代码解析

/* 打开SCM */
SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (),……)
if (sc_mgr != 0)
{
/* 获取服务句柄 */
this->svc_sc_handle_ = ACE_TEXT_OpenService (sc_mgr,……)
/* 关闭SCM */
CloseServiceHandle (sc_mgr);
}
/* 返回获取到的服务句柄 */
return this->svc_sc_handle_;

wait_for_service_state部份关键代码解析

/* 获取当前时间 */
ACE_Time_Value time_out = ACE_OS::gettimeofday ();
/* 加上等待时间 */
if (wait_time != 0) time_out += *wait_time;
// Poll until the service reaches the desired state.
for (;
{
/* 查询当前状态 */
service_ok = 0 != QueryServiceStatus (this->svc_sc_handle_, &this->svc_status_);
/* 如果已经到达指定状态,退出循环 */
if (desired_state == this->svc_status_.dwCurrentState) break;
/* 如果超出指定时间,退出循环 */
if (wait_time != 0 && ACE_OS::gettimeofday () > time_out )
{ ……
break;
}
/* 睡眠等待 */
::Sleep (this->svc_status_.dwWaitHint);
}

report_status部份关键代码解析
/* 告诉系统服务新的状态 */
SetServiceStatus (this->svc_handle_,&this->svc_status_) ? 0 : -1;

 

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=748930

你可能感兴趣的:(ACE_NT_Service(WINDOWS)