如何把你的应用程序作为服务来运行
如何把你的应用程序作为服务来运行
by Chris J. Duke
翻译:Atai
原创http://vbwire.com/advanced/howto/service.asp
本文章是“How—To”特别系列的第一部分。
如果你已经精通VB,并且现在你正想发布你的最后杰作作为商业软件。在最后的时间里,你们老板告诉你:你的应用程序需要在Windows NT下必须作为服务来运行。你告诉你们老板:“没问题“。于是你回到你的工作位置,然后发现你的VB程序不能做到。于是你到Microsoft Knowledge Base寻求答案,你在网上搜索,你在新闻组里搜索,最后你在这儿就特别兴奋,这儿就是VB程序如何做为服务这一系列。现在你所认为不可能的事情变得比你曾经想象的要简单。
本文章将把注意力集中到如何在Windows 95 和Windows NT3.51和或者更高版本来把你的Visual Basic4.0 或者Visual Basic5.0程序作为服务来运行。当你的应用程序作为服务时,你的应用程序能在登陆之前启动,这样你的程序能够在启动的时候运行。这样对于网络程序(比如Web服务器,邮件服务器或者是其他任何那些需要一直运行的应用程序)是很有用的。
请参看下一篇文章,这篇文章是关于如何下载一个免费的ActiveX控件加载到你的Form上马上把你的VB应用程序很简单的设置为NT 服务。
Window95
你可能要问你自己,为什么你需要把你的应用程序在Windows95上作为一个服务来运行。你也可能问是否Window95像WindowNT能够把你的应用程序作为服务来运行。
没错,Window95能够想Windows NT那样把应用程序作为服务来运行。为什么你将能够做到的理由就是你将在登陆之前启动你的应用程序。这经常会在Web服务器以及邮件服务器上使用。因为Windows 95的安全缺乏性,把你的应用程序作为服务将变的相当简单。但是这种情况对于Windows NT来说不适合(请看下面)。
在Windows95把你的应用程序作为服务来运行是很简单的。所有需要做的就是修改注册表。但是对于Windows NT来说却是一个地狱,对于Windows95,不要认为它毫无难处。本节将给你提供一个对Windows95重要的工作。
为了在Windows95中把你的应用程序作为一个服务,增加一个字符串值到你的注册表中:
HKLM\SOFTWARE\Microsoft\
Windows\CurrentVersion\RunServices
例如。假设你的应用程序叫“MicroSpud“,创建一个字符串值,值为:MircoSpud”,并且输入可执行文件的全路径到注册表的数据域中。下面是其步骤:
Step 1: 增加一个新的字符串值
Step 2: 输入可执行文件路径
Step 3: 全部完成,重新启动,MicroSpud将在登陆前启动
Windows 95托盘图标
现在你好记得在前面提到的“Quirk”吗?它在这里。如果你的应用程序启动,并且有托盘的话,你将想阅读这个对之地详细说明。
当你的应用第一个启动,你最有可能在Form_Load()或者Main()事件中添加你的托盘图标。如果通过重新启动Windows95被设为自动登陆,那么这个问题将不存在。尽管如此,当一个用户强制登陆的话,将发生以下的事情:
- Windows95 启动
- 你的应用程序作为服务
- 你的应用程序视图加载托盘图标,但是失败,因为已经没有托盘图标被加载
- 登陆对话框出现
- T用户输入用户名和密码
- 桌面开始加载
- Y你的图标在托盘区不会出现
解决方案是重复的调用Shell_NotifyIcon()API直到它返回一个TRUE布尔值。我发现一个来实现它的解决方法是加上一个计时器。计时器初始化为启动状态,时间间隔为5秒。在调用计时器的事件(Timer1_Timer)时调用Shell_Notification()。一旦API返回TRUE值时,关闭计时器。
Window NT
你可能已经发现在Windows95中设置只需要一步,但是对于WindowsNT来说,和Windows 95完全不一样。有些人可能称之为魔鬼,这种方法能够在WindowNT3.51或者更高版本上使用。
为什么Window NT有很大的不同呢?其中的一个理由是因为所有在NT下的服务都有服务控制台(Service Control Manager ,SCM)来管理。但是你的应用程序信息仍然在注册表里。
有更多的Keys允许应用程序作为NT服务。
微软意识到这个问题不仅仅发生在VB应用程序上,而且发生在大部分应用程序上。所以微软提出一个解决方案,并且这个解决方案表现非常出色。他们开发了一个小的应用程序。这个应用程序在Windows NT资源包里发行,他们可以在章的后面可以得到。这个应用程序叫
SRVANY.EXE,对你的应用程序来说它作为一个主机(或者服务包)。换句话说,它变成一个服务程序,这个服务程序为你处理全部的苦活(Dirty Work)和以及与SCM通信。当它启动时,它到注册表找出你的应用程序的所在路径。如果找到应用程序,则启动它。使用它唯一的缺点就是当SCM关掉SRVANY时,它将使用TerminateProcess()API来杀掉你的VB应用程序。这个是一个非常不友好的方式来关闭一个应用程序。
你的应用程序作为服务的配置是直接向前的(straight forward),但是并不和Windows95那样简单。在我向你展示一步步的操作之前。理解继续做的事情非常重要。
这有两个微软开发的程序,这两个程序欺骗它。首先是我提到的SRVANY.EXE,SRVANY位于WINNT\SYSTEM32目文件夹下。你的应用程序也在这个文件夹下。在你想把你的应用程序变为服务的最后,它确实是一个“精华“,这个”精华“是一个真正的服务。当你的服务启动时,它实际上启动的是SRVANY,SRVANY将启动你的应用程序。
第二个程序是微软开发的,叫INSTSRV.EXE。这个程序安装SRVANY来作为一个服务,INSTSRV.EXE是一个通过命令行来实现其功能的。你先前使用的不在需要,除非你打算添加另外一个使用SRVANY的服务,或者是卸载先前加的服务程序。手动保持她!
SRVANY提供了一个文档没这个文档描述了你使用它的步骤。这里将指导你一步一步安装SRVANY(SRVANY是基于程序“MircoSpud“的)。
假设:
· 你作为Administator登陆,否则你将不能安装一个服务
· 你的VB应用程序“MicroSpud”位于c:\Program Files\MicroSpud\mspud.exe
· 你已经把SRVANY。EXEINSRTSRV。EXE安装到MicroSpud文件夹下
Step 1:使用INSTSRV。EXE安装SRVANY。EXE作为服务
Step 2:确认你的服务在服务控制台(控制面板)上已被加上
Step 3: 配置你的服务设置(图为缺省)
At this point, your service has been created. However, if you were to try to start it now, it would fail. You next have to tell SRVANY where your VB application resides, so it can start it when the SCM starts SRVANY. Follow these steps to complete the installation of your new service:
在这一点上,你的服务已经被创建。但是当你试着启动它时,将会失败。你下一步必须告诉SRVANY你的VB应用程序在哪里,因此当SCM启动SRVANY时SRVANY可以启动你的应用程序。下面这些步骤降教你完成你的新服务的安装。
Step 1: A 添加“Parameter”关键字
1. 启动注册表编辑器
2. 在HKLM\SYSTEM\
CurrentControlSet\Services\MicroSpud 找出你的服务
3. 创建一个 "Parameters" 关键字
Step 2: 添加 "Application" 值:
1. 打开 "Parameters" 关键字
2. 在"Parameters" 关键字里创建一个"Application" 字符串值 (REG_SZ)
3. 编辑 "Application" 以及明确应用程序的可执行文件的全路径(包括扩展路径)
Step 3: 增加可选值(Optional Value)
虽然不是必须,但是你可能希望为“parameter”关键字加上一个可选值(Optional Value)
1. AppParameter(字符串)-描述你的应用程序的任何参数
2.AppDirectory(String)-描述你的应用程序的当前目录
祝贺你,你已经成功的将你的VB程序转化为Windows NT 服务。在这一点上,你可能很迫切测试它。因此,关闭计算机,然后重启。你的应用程序将在登陆之前启动,并且在你的左面出现之前开始运行了。
这里仍然有许多的其他信息你需要知道。这些时关于SRVANY以及新的NT服务应用程序:(尽管MicroSpud使用通过一致的例子)
- 注册表值没有大小写之分
- 为了卸载你的服务,使用INSTSRV。EXE,比如INSTSRV MicroSpud REMOVE
- 有三种方法启动你的服务:
1. 从控制面板的服务台
2. 使用SC.EXE ,例如: SC start MicroSpud
3. 使用NET.EXE , 例如: NET START MicroSpud
- 有三种方法停止服务
1. 从控制面板的服务台
2. 使用SC.EXE,例如: SC stop MicroSpud
3. 使用NET.EXE , 例如: NET STOP MicroSpud
- . 当服务停止后。它会通过Win32 TerminateProcess()API 终止应用程序.这种终止应用程序的方式是非常粗暴的。比如,它将允许应用程序弹出对话框提醒用户保存。因此,建议在关闭服务之前关闭应用程序。
- 你可能多次安装SRVANY。EXE,且使用不同的注册表参数(比如,运行不同的目标程序)――仅仅对于每个实例使用不同的服务名字(比如,MicroSpud1,MicroSpud2等)
如果你的VB应用程序和桌面交互。务必通过点击相应服务的“设置”按钮配置它来做到此功能。你应该注意这些编程的考虑。为了捕获到我们提到的消息,你学要使用一个程序比如SpyWorks。
- 对于WIN32图形应用程序:当当前用户注销后。所有的WIN32高层的窗口将收到WM_QUERYENDSESSION 和WM_ENDSESSION消息。一些WIN32应用程序选择在这些消息之上终止。为了你的WIN32应用程序幸免注销,千万不要做:代替之的是,你的Windows过程(procedure)应该调用在这些消息缺省的Windows过程
- 对于WIN32控制台程序(比如字符模式):当当前登陆的用户已经注销。所有的控制台程序从控制台收到CTRL_LOGOFF_EVEN事件。
- 如果你的控制台程序已经注册了一个控制台事件的话(通过SettConsoleCtrlHandler),它将必须忽略CTRL_LOGOFF_EVEN事件以至幸免被注销。
微软也建议你:
- 如果SRVANY启动你的应用程序失败,试着制定在注册表里的目录(参看“AppDirectory”注册表关键字)作为当前目录。SRVANY可能在某个帐户下运行,这个帐户不同于当前登陆用户,因此环境变量应该设为不一样,比如,系统可能不能找到应用程序所需要的DLL,从应用程序的目录运行它可能有帮助。
- 因为受到WindowsNT服务的限制,应用程序能交互(有控制台,读取键盘输入等)或者网络访问(但是两者不能同时进行)。
服务的依赖性
你应该知道的SRVANY的一个非正式的特性(实际上适用于所有的服务)是“DependOnServce”值。假设你的服务依赖其他服务。当你的服务启动的时候你的服务如何知道其他的服务能够利用呢?比如,让我们说你的服务是一个Web服务器。你将想保证TCP/IP是可用的在你的服务启动之前。
在服务键(Key)下二进制值能够加到你的服务下,还有其他的值你如“DisplayName”,“ObjectName”等。让我们看一下下面的屏幕截图。它反映了对于MicroSpud服务,一个对TCP/IP和事件日志的依赖。为了找到服务的名称来输入到对话框,使用该服务的注册表键(key)。比如,在HKLM\SYSTEM\CurrentControlSet\Services 下的 TCP/IP,它的键值是“Tcpip”。或者对于事件日志,你将输入“EventLog” 。为了描述对于一个地依赖,使用00作为分隔符,在ASCII显示中将显示一个周期(.)
Windows 95 and Windows NT 服务
这篇文章吧注意力集中到配置你的VisualBasic4.0或者是5.0应用程序在Windows95和Windows NT3.51或者更高版本下作为服务来执行。随着Visual Basic5.0的发布,但是VisualBasic5.0的新的兼容性对于Vb程序员来说永远不会利用,尽管如此,你仍不能创建本地的NT服务。根据 Desaware的广告。他们的新SpyWorks5.0产品允许你绕过SRVANY创建Visual Basic NT服务。我将回顾一下这个产品(OCX服务也顺便)以及在将来更新本篇文章。
我希望你能发现这个信息是有用的。他为更进一步的VB网站(http://vb/duke.net)的读者免费提供。全部或者部分地复制品被禁止。欢迎你的建议和反馈。尽管如此,我恐怕不能对SRVANY和INSTSRV提供技术支持。青联系微软的技术支持或者在他们的 knowledge base寻求帮助。
下载SRVANY
为了下载SRVANY.EXE, INSTSRV.EXE, 以及支持文档。点击下面连接。在这篇文章写的时候(Q2 1997)是最新的版本。支持WindowsNT3.51和Windows NT 4.0