Windows服务程序一例
时间:2007-01-18 来源:rockins
Windows服务程序一例
(陈云川 [email protected] UESTC,CD)
1 起因
事情的起因是这样的:我有两台机器,不妨假定为机器A和机器B,两台机器处于不同的网络中。其中,主机A所在的网络采用DHCP动态分配IP地址,主机B采用手动指定的静态IP地址。大多数情况下我在B主机上工作,但是经常需要远程登录到A主机获取资料。现在,A主机上运行的是Windows XP,远程登录方式为RDP。
面临的一个问题是:每次当我请别人帮我把A主机启动之后,由于A主机所在的网络采用DHCP动态分配IP地址,因此我就不得不让人登录进系统,查看了IP地址之后再告诉我。一次两次倒还可以接受,次数多了,就嫌麻烦。既然我常用的B主机的IP地址是固定的,那么我就希望每次A主机启动之后能够自动把IP地址通报给B主机,这样我就不用再麻烦了。怎么办呢?我当然首先想到了守护进程。不过Windows下没有守护进程的概念,取而代之的是服务(service)。那么,就编写一个简单的服务程序罢,每次机器启动之后自动连接到B主机的某个UDP端口上(本例中连接到UDP端口8277),而运行在B主机上的服务程序就可以打印出A主机的IP地址了。如此,不管DHCP给A主机分配的IP地址怎么变,我再也不用浪费时间在搞到A主机的IP地址这种琐碎的事情上了。
之前并没有接触过Windows服务程序的编写,不过既然都遇到了。那么就看看文档吧。Windows提供了一大堆API用于服务程序的编写,如下所示:
ChangeServiceConfig
CloseServiceHandle
ControlService
CreateService
DeleteService
EnumDependentServices
EnumServicesStatus
GetServiceDisplayName
GetServiceKeyName
Handler
LockServiceDatabase
NotifyBootConfigStatus
OpenSCManager
OpenService
QueryServiceConfig
QueryServiceLockStatus
QueryServiceObjectSecurity
QueryServiceStatus
RegisterServiceCtrlHandler
ServiceMain
SetServiceBits
SetServiceObjectSecurity
SetServiceStatus
StartService
StartServiceCtrlDispatcher
UnlockServiceDatabase
不过我用不了这么多,给我一套最小的工作集合足矣!我只需要下面这些API:
StartServiceCtrlDispatcher()
ServiceMain()
RegisterServiceCtrlHandler()
SetServiceStatus()
Handler()
加上这样几个结构体:
SERVICE_TABLE_ENTRY
SERVICE_STATUS_HANDLE
SERVICE_STATUS
万事俱备!
2 发送端实现
发送端的实现在ipnotify_cli.c文件中。抛开Windows服务程序编写的相关规范来看,程序本身是很简单的,就是一个只发不收的UDP程序而已。简单得让人不忍赘述。另外,作者是用DEV-CPP编译该程序的,需要链接libws2_32.a,这个库文件中包含了Windows的套接口函数的实现。编译得到的程序是不能直接运行的,必须要注册为服务之后从Windows服务管理器中启动才行。有关服务注册和启动,请google之。附件中的SRVINSTW.exe是用来安装服务的,使用非常简单,请大胆实践。
3 接收端实现
作者所用的B主机为一台运行Linux的机器,因此,接收端的程序是采用Linux的套接口函数来编写的。当然,无论是Linux还是Windows,套接口都是相似的,但是差别总还是有那么一些。附件中一并附上接收端的源代码实现ipnotify_svr.c。
4 结论
个人感觉,在Windows下弄一个守护进程始终要比Unix类系统下麻烦一些。不过也可能是我不习惯罢了。
5 参考
[1] Microsoft®Win32®Programmer's Reference
[2] man socket(2)等
附:
ipnotify_cli.c的实现:
/* |
ipnotify_svr.c的实现:
/* |