用Delphi编写Win2000服务程序

一、Win2000服务简介

服务程序(Service Application)是一种运行于WinNT的后台程序,每个服务 程序(Service Application)中可能包含若干个服务(Service),每个服务就 是其中的一个线程(该服务也可以创建多个子线程)。采用服务,应用程序可以 获得特殊的权限,而且不会被用户通过Win2000的任务管理器直接结束程序,所以 服务常常用来实现一些特殊的目标。

通过Win2000控制面板中的服务管理工具,我们可以设置/查看服务的特性:

(1)服务名称;(2)显示名称;(3)描述;(4)启动类型;(5)依赖关 系;

其中,服务名称是标识给服务的。

以Win2000的C:\WINNT\System32\services.exe程序为例子,该Exe文件对应一个 Service Application,是该服务程序的可见实体;该exe中包含多个服务 (Service),例如Alerter,Dhcp(DHCP Client),Messenger等。当我们结束 一个服务的时候,该服务所在的Service Application中的其他服务并没有被终止 。

在Delphi中,Borland的工程师为我们提供了TServiceApplication,TService ,TServiceThread等类,封装了大量细节,简化了服务程序的开发。

二、TServiceApplication

在Delphi中,类TServiceApplication就对应上述的ServiceApplication。利 用Delphi的开发环境,我们新建一个Service Application Project,同时就创建 了一个继承自TService的类。项目文件中的Application对象就是一个 TServiceApplication实例。每个TServiceApplication包含若干个TService对象 ,正好对应上述的服务程序和服务之间的数量关系。

通过阅读TServiceApplication和TService类的定义,可以得知, TServiceApplication从TComponent类继承而来,TService从类TDataModule基础 而来,Application对象负责各个TService对象的Create和Destroy。跟踪下列代 码

Application.CreateForm(TService1, Service1);

可以发现创建的TService对象的Owner都是Application对象;在VCL Framework中Owner总是负责Destroy各个Component对象(VCL的TComponent类采用 了Composite模式),所以TServiceApplication也将Destroy各个TService对象。

下面跟踪TServiceApplication.Run的代码,可以发现TServiceApplication首 先解析运行参数,实现了服务的Install和Uninstall。然后,初始化一个 ServiceStartTable数组,该数组包含了各个service对象的服务名称和运行入口 ;最后创建一个TServiceStartThread 对象,该对象是一个线程对象,从线程调 用API:StartServiceCtrlDispatcher来启动ServiceStartTable中指定的若干个 服务;而ServiceApplication主线程就不断循环,处理消息,比如接收请求来停 止/暂停某个服务。

三、TService

TService类继承自类 TDataModule,这意味着我们可以加入大量的VCL控件, 实现丰富的功能。此外,我们还可以处理OnStart,OnPause,OnStop, OnContinue,OnCreate,OnShutDown等事件。其中需要说明的是:OnStop表示该 服务被停止;而OnShutDown表示该ServiceApplication停止运行,这意味着其他 服务也被终止了;两者含义是不一样的。

前面讲过,ServiceApplication通过调用StartServiceCtrlDispatcher来启动 各个服务。StartServiceCtrlDispatcher启动TService的入口,该入库就是 TService.Main。TService.Main首先注册该服务,然后调用TService.DoStart。 TService.DoStart创建一个内部TServiceThread成员对象,这是一个线程对象; 考察TServiceThread.Execute可以得知,当我们处理的TService1. OnExecute, 那么TService会把所有的请求委托给该TServiceThread成员对象处理,该对象以 默认的方式处理所有的请求。

TService. ServiceExecute是TService的主体内容。一个服务要正常运行,除 了需要处理它要关注的目标(比如监听某个端口、执行某个任务等)外,还要响 应外部命令/请求:比如终止、暂停、恢复该服务。因此可以考虑创建一个专门的 线程来完成该任务,而在ServiceExecute中处理外面命令/请求。因此代码如下:

while not Terminated do begin
 ServiceThread.ProcessRequests(False);
end;

当然,也可以在OnExecute中处理某些任务,如监听某个端口,但是这常常会 导致该Service不能及时响应Stop/Pause等请求。当OnExecute执行完了,该服务 实际上就完成了任务要结束了(terminate)。

时间: 2024-11-01 21:50:38

用Delphi编写Win2000服务程序的相关文章

Delphi编写组件封装asp代码的基本步骤

如果你想脱离asp爱好者的水平,那么你就应该学会为asp编写组件.我在google上搜索了一下,Delphi编写asp组件的文章一共就几篇,所以今天写了这篇Delphi编写asp组件的基础文章,希望对新手有点帮助.    开始吧,让我们一起编写一个"hello world!"的示例.我这里用的是Delphi 7.     1.文件->新建->其他->ActiveX->ActiveX Library,然后保存成showdll.dpr 2.再次,文件->新建-

用Delphi编写安装程序

当你完成一个应用软件的开发后,那么你还需要为该软件做一个规范化的安装程序,这是程序设计的最后一步,同时也是很重要的一步,因为运行安装程序往往是用户做的第一步操作. 很多报刊文章介绍了许多如何利用installshield等工具软件来制作安装程序的方法,这种办法可以很快建立起较常见的安装模式,但用这种办法也有一些不足,如做成的安装程序一般较大:风格较单一:不能灵活的控制启动方式和快捷方式.其实安装程序的的几个运行步骤较固定,我们完全可以自己来编写安装程序.下面就详细介绍如何用DELPHI编写具有自

传递和返回数据到一个Delphi编写的UDF

数据 [UDF系列之四]:传递和返回数据到一个Delphi编写的UDFWarton译作者: Chris Levesque, Tina Grubbe, Brett Bandy -------------------------------------------------------------------------------- [译者叙]: 前面我已经翻译了几篇关于编写UDF的文章,虽然一些朋友可能也从中得到了一点帮助,但是可能对UDF的认识还存在一些问题.今天,我再翻译两文章,这两篇文章

用C编写Windows服务程序的五个步骤

Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务.为了学习这种控制台应用程序的基础知识,C(不是C++)是最佳选择.本文将建立并实现一个简单的服务程序,其功能是查询系统中可用物理内存数量,然后将结果写入一个文本文件.最后,你可以用所学知识编写自己的 Windows 服务. 当初我写第一个NT 服务时,我到 MSDN 上找例子.在那里我找到了一篇 Nigel Thompson 写的文章:"Creating a Simple Win32 Service in C++&

用Delphi编写可被其它语言调用的DLL

在所开以的应用软件中,有时我们对某些文件进行拷贝(如对数据库进行备份.制作安装程序),但是常用的一些语言却没有提供可直接进行文件拷贝的过程或函数.为此,我曾利用Delphi编制了可提供文件拷贝过程的动态连接库Copy.dll,其输出过程为CopyFile.由于DLL具有简化编程.运行速度快等诸多优点,且不受编程语言的限制, 用Delphi编写的Copf.dll同样被VB.VC等面向对象语言进行静态或动态调用,人而方便地在程序中实现文件拷贝. 附源程序如下: library copf; uses

用Delphi编写数据报存储控件

一.概述 在用Delphi编写数据库程序时,经常涉及到数据的导入和导出操作,如:将大型数据库中的数据存储为便携文件,以便于出外阅读:将存储在文件中的数据信息,导入到另外的数据库中:而且,通过将数据库中的数据存储为数据文件,更便于程序内部和程序间交换数据,避免通过内存交换数据的烦琐步骤,例如在笔者编写的通用报表程序中即以该控件作为数据信息传递的载体. 二.基本思路 作为数据报存储控件,应能够存储和读入数据集的基本信息(如:字段名,字段的显示名称,字段的数据类型,记录数,字段数,指定记录指定字段的当

断点-关于delphi编写的程序在某些操作系统上运行出错的问题

问题描述 关于delphi编写的程序在某些操作系统上运行出错的问题 大家好 本人从事程序测试工作3年左右 还属于菜鸟级别 目前遇到了一个比较棘手的问题 希望高手可以指点 关于delphi编写的程序在某些操作系统上运行出错的问题:同样的程序在xp系统可以正常运行 在win7某些系统可以 某些系统不行(即使是win7旗舰版32位正常安装的已经打上sp1补丁的系统) 所加的断点不起作用 不能够显示 直接抛系统错误(外部组件异常之类的) 希望精通delphi程序以及操作系统的高手可以指点下 如果可以远程

vc++-新人求帮助:VC6 调用delphi编写的com组件函数 报错

问题描述 新人求帮助:VC6 调用delphi编写的com组件函数 报错 代码: IElectric *ptr = NULL; CLSID clsid; HRESULT hr = CLSIDFromString((LPOLESTR)L"{18F86FFB-158B-42D6-9203-C4197A4E76FE}",&clsid); hr = CoInitialize(0); if(!SUCCEEDED(hr)) { int nCode = GetLastError(); } h

学习编写C#服务程序,遇到了问题,求指教

问题描述 学习编写C#服务程序,遇到了问题.按照步骤写了个空的C#服务程序,.安装上电脑之后,直接就被电脑管家给设定为禁用...这是怎么回事儿..如何避免..最后,我手动设置启动,重启才出现我的服务程序.怎么才能不被电脑管家禁用? 解决方案 解决方案二: 解决方案三:那你应该问这个什么管家的作者,为什么要禁用你的服务解决方案四:卸载管家......解决方案五:添加白名单解决方案六:一般管家都会提示是否允许服务启动,选择允许就可以了.解决方案七:引用3楼plcly1的回复: 卸载管家......