一、NT服务程序
所谓NT服务,实际上就是一个可以在系统启动时自动在一定身份下启动的伴随系统长时间存在的进程。象FTPserver、HTTPserver、脱机打印等都是采用NT服务的形式提供的。这实际上类似Unix的rootdaemon进程。NT服务归纳起来,NT服务又以下几个特征:
1、可以自启动,不需要交互启动。这对于服务器来说是一个重要的特征。当然,你可以决定服务是否自启动,甚至可以屏蔽某个服务。
2、NT服务没有用户界面,基本上类似一个DOS程序,因为NT服务必须长时间运行,所以不想普通win32进程一样有自己的界面。但是NT服务可以同用户有界面交互,这是一类特殊的服务进程。可以通过NT的任务管理器来看到服务进程。
3、NT服务通过SCM(ServicesControlManager)接口来管理,安装、启动、停止、撤除等都需要SCM的接口功能来进行。控制面板的服务控制器就是利用SCM接口来管理系统中的所有服务的。实际上,还有一些可以控制服务的程序或者命令,有net.exe、服务器管理器等、SCM.exe等。
4、这些进程都以一定的身份运行,以方便进行服务器资源的存取。一般情况下使用域中的LocalSystem账号运行,此账号对本机上的大多数资源(除非特别禁止)有完全的存取权限,这样可以保证服务程序的“强大”。但是,也有些服务采用特别的账号运行,你也可以特别设定一个服务的帐号。
5、由系统自动以线程方式运行,一般情况下不过多占用系统资源,这同普通的进程有所区别,如果不采用线程方式,一般进程往往消耗整个CPU资源。一般需要时时存在,又不能过多消耗资源的任务以服务来实现最合适。
二、服务控件
一般认为编写NT服务需要使用C/C 来实现,VC6利用ATL向导来提供一个基本的服务框架。具体实现步骤为:FileàNew…àATLCOMAppWizardàserviceàFinish.但是使用VC编写NT服务需要编写太多的代码,这也意味着需要太多的调试、维护。实际上,NT服务不是必须由C/C 才可以编写的,实际上可以由任何能够实现上一节几个特点的任何语言实现,包括VB。
VB编写服务有那些好处呢,至少可以列出以下几条:
1、编码简单,熟悉Vb语法的任何人理解本文后都可编写。
2、意味着修改服务实现的逻辑简单,维护简单。
3、可以利用几乎大多数的Vb中的组件功能,编写一个强大的服务,譬如ado等,如果用VC来实现,相信任何人都会发怵。
4、(牵强一点)可以证明Vb在Bill的天空下是多么强大。
那么,Vb如何实现NT服务编写呢?据我所至,至少有两种途径:
1、按照C/C 的思路利用WinAPI来实现。
2、利用组件按照Vb传统方式实现。
如果利用方法1实际上是照搬C/C 的套路,如果有更好的路子可以实现,相信任何人都不会走这条“绝路”,因为相对于其他语言来说这种编程完全丧失了Vb自身得特点同时也没有获得其他语言的任何优势。在这里,想告诉大家的是利用OCX来实现一个服务。如果您在MSDN中搜索Samples\msdn\techart\4920\,您可以看到一个已经编写好的vc5的工程文件。编译这个工程实际上会得到一个ntsvc.ocx的。如果您对C/C 不熟悉,可以从NTService1.Interactive=True
IfNTService1.InstallThen
CallNTService1.SaveSetting("Parameters","TimerInterval","1000")‘系统参数存储
MsgBoxstrDisplayName&"安装成功!"
Else
MsgBoxstrDisplayName&"安装失败"
EndIf
End‘终止安装
Else
IfCommand="-uninstall"Then‘如果启动时带上撤除参数
IfNTService1.UninstallThen
MsgBoxstrDisplayName&"撤除成功"
Else
MsgBoxstrDisplayName&"撤除失败"
EndIf
End‘终止撤除
Else
EndIf
EndIf
‘假若不是安装或撤除操作,即为启动服务
Timer1.Interval=CInt(NTService1.GetSetting("Parameters","TimerInterval","2000"))
‘使用Timer控件来模拟服务的线程特性
NTService1.ControlsAccepted=svcCtrlPauseContinue‘接受暂停、停止操作,意味着需要为此编码
NTService1.StartService‘设置好参数后启动服务
Err_Load:
CallNTService1.LogEvent(svcMessageError,svcEventError,"["&Err.Number&"]"&Err.Description)‘svcMessageError为NT服务控件的错误值
4、添加控制服务的代码。
尽管服务的连续线程等特性是依赖Timer实现的,但是服务的控制却是有SCM接口向每一个服务发出的,表现在VB服务程序中为NT服务控件捕获到相关的事件发生,我们就应当在这些事件中根据具体的情况响应,决定能不能、如何控制服务逻辑。当然,具体的逻辑在Timer事件中表现,但是通过改变NT服务控件和Timer控件均支持的全局变量,可以实现控制服务的逻辑实现。具体代码演示:
PrivateSubNTService1_Control(ByValEventIDAsLong)
OnErrorGoToErr_Control
‘在此加入一些自己的处理逻辑,当然也可以如本例一样空缺
Err_Control:
CallNTService1.LogEvent(svcMessageError,svcEventError,"["&Err.Number&"]"&Err.Description)‘纪录
EndSub
PrivateSubNTService1_Pause(SuccessAsBoolean)
OnErrorGoToErr_Pause
Timer1.Enabled=False‘禁止Timer事件,因此也停止了服务的发生
CallNTService1.LogEvent(svcEventError,svcMessageError,"Servicepaused")
Success=True‘返回给SCM命令发出者,表示服务成功停止
Err_Pause:
CallNTService1.LogEvent(svcMessageError,svcEventError,"["&Err.Number&"]"&Err.Description)
EndSub
PrivateSubNTService1_Start(SuccessAsBoolean)
OnErrorGoToErr_Start
Success=True
Timer1.Enabled=True‘允许服务逻辑进行
Err_Start:
CallNTService1.LogEvent(svcMessageError,svcEventError,"["&Err.Number&"]"&Err.Description)
EndSub
PrivateSubNTService1_Stop()
OnErrorGoToErr_Stop
UnloadMe‘撤除Form,自然Timer也不存在,服务逻辑停止了
Err_Stop:
CallNTService1.LogEvent(svcMessageError,svcEventError,"["&Err.Number&"]"&Err.Description)
EndSub
5、编写服务逻辑。
具体就是在Timer事件中,根据约定写一些服务细节。本例中就是发出Been,但是考虑到对SCM命令的响应,所以需要编码为:
OnErrorGoToErr_Timer
Beep‘此处即具体的服务细节
Err_Timer:
CallNTService1.LogEvent(svcMessageError,svcEventError,"["&Err.Number&"]"&Err.Description)
EndSub
6、编译安装、测试
如果以上没有什么错误的话,现在可以编译程序了。假设我们得到的服务程序的文件名为:VBBeepSVC.exe,我们需要通过以下命令进行安装:
d:\vbprog\>VBBeepSVC–install
如果需要撤除已经安装的服务,则:
d:\vbprog\>VBBeepSVC–uninstall
安装完后,打开控制面板的“服务”(win2000中在“管理工具”),好了,看到其中的NT服务列表中包含我们加入的服务,显示为:“TheVBNTSVCView”,我们可以类似启动其他任何服务一样启动、停止、暂停此服务。启动服务时,我们会听到服务发出的讨厌的beep声音。我们的测试完成。
四、VB编写服务的几个说明:
1、首先声明:VB编写服务是一种尝试,技术研究,并非提倡所有服务都要用VB写才对头。同理,也说明了服务非VC写不可。
2、VB写的服务仅适合win32服务,不适合NT底层服务。
3、VB的优势在ActiveX控件,NT服务中我们可以使用绝大多数控件来完成我们的服务逻辑,譬如涉及数据库操作,我们可以使用ADO组件,这方面,同VC相比,VB具有天然的优势。
4、做好服务内部的错误事件记载,只有用好这一点,才能够真正符合服务编写规范,也方便我们的除错。
发表于 @ 2008年05月22日 09:34:00|评论(loading...)|编辑