ACE_NT_Service(WINDOWS)

转载 2006年05月22日 10:25:00

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;

 

 

基于ACE的后台服务程序的实现

后台服务进程不属于任何一个终端会话,当然也就不用和任何用户交互,许多系统服务由后台服务进程实施;如网络服务,打印等。Windows和LINUX在实现后台服务进程上并不统一,Windows定义的名称为S...
  • inrgihc
  • inrgihc
  • 2015年10月20日 21:34
  • 563

NT Service 编程 操作 NT 服务

操作 NT 服务: OpenSCManager   打开目标计算机上的“服务控制管理器”-SCM,返回指向该管理器的指针。 OpenService     打开服务,返回指向该服务的指针。 St...
  • thanklife
  • thanklife
  • 2017年04月07日 16:29
  • 212

Install_NT_Service

  • 2008年08月30日 10:48
  • 41KB
  • 下载

ACE_NT_Service(WINDOWS)

ACE_NT_Service(WINDOWS)本人的观点,SERVICE就是WINDOWS版的DAEMON。ACE_NT_Service通过包装一整套WINDOWS提供的SERVICE API定义了一...
  • DNCS
  • DNCS
  • 2006年05月22日 10:25
  • 2851

如何用ACE来实现一个windows Service

好久没来写技术文章,归结原因依旧是很忙。 有时间就多写一些吧。 最近有朋友在我的开源服务器上做了一个windows服务版本,挺有趣,于是我想把这个功能和我的服务器做一个整合,一开始并不顺利,原因是...
  • free_eyes
  • free_eyes
  • 2014年11月04日 09:10
  • 569

ACE的Linux移植及静态库编译

在Linux下编译ACE,和在AIX下编译,没有什么本质区别,不过是选用不同的config而已。这里可以参见前一篇Blog《ACE移植心得》,这里在Linux下分别选用config-linux.h和p...
  • hanyu1980
  • hanyu1980
  • 2006年09月29日 11:36
  • 3303

Windows进程间各种通信方式浅谈

1 Windows进程间通信的各种方法 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码、数据以及它可利用的系统资源(如文件、管道等)组成。 多进程/多线程是Wind...
  • left_la
  • left_la
  • 2013年09月11日 14:54
  • 23395

ACE网管平台移植Linux

 我们的网管平台基于ACE, ODBC,SNMP ++的,都是可以跨平台的库,但一直未进行linux下的编译测试,这是去年移植测试时记录的日志。 注意移植前先要编译好ACE, unixODBC,SNM...
  • stephenxu111
  • stephenxu111
  • 2008年05月14日 19:18
  • 2278

omniORB-4.0.0环境配置 for window

在win32(Windows NT, 2000, 95, 98)上,omniORB 首先去找环境变量OMNIORB_CONFIG以便去获得配置文件omniORB.cfg的路径,如果没有找到的话,就去注...
  • DNCS
  • DNCS
  • 2006年05月05日 16:07
  • 2745

Windows管道通信实现进程通信

Windows下用管道通信(pipe)实现进程间数据共享管道是一种用于在进程间共享数据的机制,其实质是一段共享内存。Windows系统为这段共享的内存设计采用数据流I/0的方式来访问。由一个进程读、另...
  • demon_xiao
  • demon_xiao
  • 2015年04月22日 17:19
  • 5773
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ACE_NT_Service(WINDOWS)
举报原因:
原因补充:

(最多只允许输入30个字)