专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »C 教程 » vc编写windows服务:Windows服务编写原理及探讨(1) »正文

vc编写windows服务:Windows服务编写原理及探讨(1)

来源: 发布时间:星期四, 2009年2月12日 浏览:98次 评论:0


有那么类应用是能够为各种用户(包括本地用户和远程用户)所用拥有用户授权级进行管理能力并且不论用户是否物理和正在运行该应用计算机相连都能正常执行这就是所谓服务了

()服务基础知识

Question 1. 什么是服务?它特征是什么?

  在NT/2000中服务是类受到操作系统优待个服务首先是个Win32可执行如果要写个功能完备且强大服务需要熟悉动态连接库(Dlls)、结构异常处理、内存映射文件、虚拟内存、设备I/O、线程及其同步、Unicode以及其他由WinAPI提供应用接口当然本文讨论只是建立个可以安装、运行、启动、停止没有任何其他功能服务所以无需上述知识仍可以继续看下去我会在过程中将理解本文所需要知识逐讲解

  第 2要知道个服务决不需要用户界面大多数服务将运行在那些被锁在某些黑暗冬暖夏凉小屋子里强大服务器上面即使有用户界面般也没有人可以看到如果服务提供任何用户界面如消息框那么用户错过这些消息可能性就极高了所以服务通常以控制台形式被编写进入点而不是WinMain

  也许有人有疑问:没有用户界面要怎样设置、管理个服务?怎样开始、停止它?服务如何发出警告或信息、如何报告有关它执行情况统计数据?这些问题答案就是服务能够被远程管理Windows NT/2000提供了大量管理工具这些工具允许通过网络上其它计算机对某台机器上面服务进行管理比如Windows 2000里面“控制台”(mmc.exe)用它添加“管理单元”就可以管理本机或其他机器上服务



Question 2. 服务安全性…

  想要写个服务就必须熟悉Win NT/2000安全机制在上述操作系统的中所有安全都是基于用户换句话说——进程、线程、文件、注册表键、信号、事件等等等等都属于个用户个进程被产生时候它都是执行在个用户上下文(context)这个用户帐号可能在本机也可能在网络中其他机器上或者是在个特殊账号: Account——即系统帐号上下文

  如果个进程正在个用户帐号下执行那么这个进程就同时拥有这个用户所能拥有切访问权限不论是在本机还是网络系统帐号则是个特殊账号它用来标识系统本身而且运行在这个帐号下任何进程都拥有系统上所有访问权限但是系统帐号不能在域上使用无法访问网络资源…

  服务也是Win32可执行它也需要执行在个context通常服务都是在系统账号下运行但是也可以根据情况选择让它运行在个用户账号下也就会因此获得相应访问资源权限



Question 3. 服务 3个组成部分

  个服务由 3部分组成部分是Service Control Manager(SCM)每个Windows NT/2000系统都有个SCMSCM存在于Service.exe中在Windows启动时候会自动运行伴随着操作系统启动和关闭而产生和终止这个进程以系统特权运行并且提供个统、安全手段去控制服务它其实是个RPC Server因此我们可以远程安装和管理服务不过这不在本文讨论范围的内SCM包含个储存着已安装服务和驱动信息数据库通过SCM可以统、安全管理这些信息因此个服务安装过程就是将自身信息写入这个数据库

  第 2部分就是服务本身个服务拥有能从SCM收到信号和命令所必需特殊代码并且能够在处理后将它状态回传给SCM

  第 3部分也就是最后部分个Service Control Dispatcher(SCP)它是个拥有用户界面允许用户开始、停止、暂停、继续并且控制个或多个安装在计算机上服务Win32应用SCP作用是和SCM通讯Windows 2000管理工具中“服务”就是个典型SCP



  在这 3个组成部分中用户最可能去写服务本身同时也可能不得不写个和其伴随客户端作为个SCP去和SCM通讯本文只讨论去设计和实现个服务有关如何去实现个SCP则在以后其它文章中介绍

Question 4. 怎样开始设计服务

  还记得前面我提到服务入口点般都是吗?个服务拥有很重要 3个个就是入口点其实用WinMain作为入口点也不是不可以虽然说服务不应该有用户界面但是其实存在很少几个例外这就是下面图中选项存在原因



  由于要和用户桌面进行信息交互服务有时会以WinMain作为入口点

  入口负责化整个进程由这个进程中主线程来执行这意味着它应用于这个可执行文件中所有服务要知道个可执行文件中能够包含多个服务以使得执行更加有效主进程通知SCM在可执行文件中含有几个服务并且给出每个服务ServiceMain回调(Call Back)地址旦在可执行文件内所有服务都已经停止运行主线程就在进程终止前对整个进程进行清除

  第 2个很重要就是ServiceMain我看过些例子里面对自己服务进入点都固定命名为ServiceMain其实并没有规定过定要那样命名任何只要符合下列形式都可以作为服务进入点

VOID WINAPI ServiceMain(
DWORD dwArgc, // 参数个数
LPTSTR *lpszArgv // 参数串
);

  这个由操作系统并执行能完成服务代码个专用线程执行每个服务ServiceMain注意是服务而不是服务这是每个服务也都拥有和自己唯对应ServiceMain有关这点可以用“管理工具”里“服务”去察看Win2000里面自带服务就会发现其实很多服务都是由service.exe单独提供当主线程Win32StartServiceCtrlDispatcher时候SCM为这个进程中个服务产生个线程这些线程中个都和它相应服务ServiceMain起执行这就是服务总是多线程原因——个仅有个服务可执行文件将有个主线程其它线程执行服务本身

  第 3个也就是最后个重要是CtrlHandler它必须拥有下面原型:

VOID WINAPI CtrlHandler(
DWORD fdwControl //控制命令


)

  像ServiceMainCtrlHandler也是个回调用户必须为它服务中每个服务写个单独CtrlHandler因此如果有含有两个服务那么它至少要拥有5个区别:作为入口点或WinMain用于第个服务ServiceMain和CtrlHandler以及用于第 2个服务ServiceMain和CtrlHandler

  SCM个服务CtrlHandler去改变这个服务状态例如当某个管理员用管理工具里“服务”尝试停止你服务时候服务CtrlHandler将收到个SERVICE_CONTROL_STOP通知CtrlHandler负责执行停止服务所需切代码由于是进程主线程执行所有CtrlHandler因而必须尽量优化你CtrlHandler代码使它运行起来足够快以便相同进程中其它服务CtrlHandler能在适当时间内收到属于它们通知而且基于上述原因CtrlHandler必须要能够将想要传达状态送到服务线程这个传递过程没有固定思路方法完全取决于你服务用途

本文测试环境为Win2000 Server + SP2
Athlon XP 1700 + 256MB DDR
全部资料参考自MSDN OCT 2001
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: