• 欢迎访问金刀客博客!
  • 2019,春节快乐!

VB程序设置为系统服务的几种办法

原创天空 admin 12280次浏览 已收录 3个评论

把VB注册为系统服务,这样每次在登陆前就已经启动你的程序,这对网站服务器,SMTP等的架设是非常有用的。这里我介绍几种把VB应用程序注册为系统服务的方法。在windows95上的方法就不讲了,非常简单,修改注册表就OK,这里主要是说在windows NT(2000,xp)等系统上注册服务的方法,借用Chris J. Duke的话说,在95上只需要一步就行,但是在windows NT系统上完全是另外一种“动物”,甚至可以称之为“野兽”。
在 windows NT下之所以注册为服务比较困难的一个原因是系统的所有服务都被Service Control Manager (SCM)所控制。应用程序要想作为服务来运行就必须支持多线程,因为它需要创建一些线程来与SCM通信。但是VB是不支持多线程的,所以不能作为本地NT服务程序(native NT service applications )来运行。
显然,微软也注意到了这样的问题,提供了几个解决办法。
在往下看之前请你看看这2篇文章
http://vbwire.com/advanced/howto/service.asp
http://vbwire.com/advanced/howto/service2.asp
1,SRVANY.EXE
这个使用方法在第一篇文章中已经有了详细说明,我之提供文件下载
点击下载此文件
2,NTSVC.OCX
这个库文件的介绍主要是在第二篇文章中介绍的。
我这里整理了一下它的几个属性

Account String , 账号属性,即本 NT 服务在哪一个 NT 域账号下运行,缺省是 LocalSystem 账号,实际上大多数的 NT 服务都可以在此账号下安全圆满的运行。
ControlsAccepted Long, 此服务接受那些 SCM 控制,为以下值:0 允许 Start 以及 Stop;2 允许 Pause 以及 Continue;4 允许 shutdown 。其他值,用户自定义的某些事件 .利用这个属性,您可以自己决定 NT 服务进程某个(譬如某个不可中断操作)时刻是否允许 SCM 停止、暂停、启动等操作。
Dependencies String , 如果您编写的服务依赖于某个或者某些服务才能正常运行,您必须在注册服务时指定依赖的服务列表。 Dependencies 按照依赖顺序以 chr(0) 来分隔多个服务,最后必须以两个 chr(0) 结束。
DisplayName String, 显示名, NT 服务以何种名字显示给察看者。
Interactive Boolean , 是否允许有同桌面用户有交互的部分。
LoadOrderGroup String, 同 Dependencies 相关,决定如果本服务启动之前,那些服务必须启动,格式也类似,也以 chr(0) 分割,连续的两个 chr(0) 结尾。
Password String, 服务启动的口令,如果使用缺省得账号,就没有必要设定服务启动的帐号。
ServiceName String, 服务名,如果使用 net.exe 来控制服务, net.exe 的指定那一个服务的参数就是此属性中的字符串。
StartMode 枚举型,具体为:
vcStartAutomatic 2 服务可以自己启动
svcStartManual 3 服务手动启动
svcStartDisabled 4 服务不能自启动
我们要将一个 VB 程序当作一个 NT 服务,必须向系统作一些“申请” , 而相应的工作 VB 是无法很好的完成的。所以, NTSVC.ocx 提供了相应的方法留作我们想系统传递相关信息。
Install , 将当前 Vb 程序安装成 NT 服务,在此之前,您必须至少设置 DisplayName, ServiceName, ControlsAccepted 以及 StartMode 等属性。除此之外您可能还要设置 Account 、 Password 、 LoadOrderGroup 、 Dependencies 等。这些信息的设置正确与否,决定您的服务程序能否正常启动运行。
Uninstall, 将当前 NTSVC.ocx 指定的服务从系统注册表中删除。 NT 服务取决于系统服务注册表的设定,这是一个众所周知的秘密。
StartService ,将指定的服务启动,如果该服务注册了。
StopService ,停止服务,如果服务正在运行。
LogEvent , 记录服务事件。服务运行中,可能发生错误以及意料不到的事件,这些可以通过此方法记录下来,供管理员通过“事件察看器”察看相关的信息,以最优化服务。此方法有三个参数 event, id, message. Event 指发生的事件类型,可以设为以下值:
svcEventError 1 错误事件
svcEventWarning 2 警告事件
svcEventInformation 4 提供参考信息
svcEventAuditSuccess 8 审计成功
svcEventAuditFailure 10 审计失败
除了以上方法,可能用户还需要读写注册表,此控件还提供了注册表的访问方法:
DeleteSetting (section[, key])
GetAllSettings(section)
GetSetting(section, key[, default])
SaveSetting(section, key, setting)

这个控件及其使用例子我会传给大家。但是我找了很久也没找到服务的描述信息是在哪里,如果你有找到告诉我了。如没有就只有通过注册表添加description了。
同时其调用也感觉不是很方便,我一直没有找到把程序自身注册成服务的方法,只能是单独安装,有文章说可以利用控件激活,不知道行不行?你可以测试下
在注册Service服务的时候,必须带/i或/u参数。/i-install,/u-unstall
NTSVC.OCX及其例子源码
3,第三种方法就是我强烈推荐的方法了,利用API来注册VB程序为系统服务,看这个方法前,推荐你看看这个作者(Sergey Merzlikin)的文章。
http://www.smsoft.ru/en/ntservice.htm
从这个域名看,作者可能是俄罗斯的。
module中的API申明如下

Option Explicit
‘**************************************************
‘* NT Service sample Control Program *
‘* ?2000-2004 Sergey Merzlikin *
‘* http://www.smsoft.ru *
‘* e-mail: sm@smsoft.ru *
‘* The code is freeware. It may be used *
‘* in programs of any kind without permission *
‘**************************************************
Private Const SERVICE_CONFIG_DESCRIPTION = 1&
Private Const ERROR_SERVICE_DOES_NOT_EXIST = 1060&
Private Const SERVICE_WIN32_OWN_PROCESS = &H10&
‘Private Const SERVICE_WIN32_SHARE_PROCESS = &H20&
‘Private Const SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS + _
SERVICE_WIN32_SHARE_PROCESS
‘Private Const SERVICE_ACCEPT_STOP = &H1
‘Private Const SERVICE_ACCEPT_PAUSE_CONTINUE = &H2
‘Private Const SERVICE_ACCEPT_SHUTDOWN = &H4
Private Const SC_MANAGER_CONNECT = &H1&
Private Const SC_MANAGER_Create_SERVICE = &H2&
‘Private Const SC_MANAGER_ENUMERATE_SERVICE = &H4
‘Private Const SC_MANAGER_LOCK = &H8
‘Private Const SC_MANAGER_QUERY_LOCK_STATUS = &H10
‘Private Const SC_MANAGER_MODIFY_BOOT_CONFIG = &H20
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const SERVICE_QUERY_CONFIG = &H1&
Private Const SERVICE_CHANGE_CONFIG = &H2&
Private Const SERVICE_QUERY_STATUS = &H4&
Private Const SERVICE_ENUMERATE_DEPENDENTS = &H8&
Private Const SERVICE_START = &H10&
Private Const SERVICE_STOP = &H20&
Private Const SERVICE_PAUSE_CONTINUE = &H40&
Private Const SERVICE_INTERROGATE = &H80&
Private Const SERVICE_USER_DEFINED_CONTROL = &H100&
Private Const SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or _
SERVICE_QUERY_CONFIG or _
SERVICE_CHANGE_CONFIG or _
SERVICE_QUERY_STATUS or _
SERVICE_ENUMERATE_DEPENDENTS or _
SERVICE_START or _
SERVICE_STOP or _
SERVICE_PAUSE_CONTINUE or _
SERVICE_INTERROGATE or _
SERVICE_USER_DEFINED_CONTROL)
‘Private Const SERVICE_AUTO_START As Long = 2
Private Const SERVICE_DEMAND_START As Long = 3
Private Const SERVICE_ERROR_NORMAL As Long = 1
Private Const ERROR_INSUFFICIENT_BUFFER = 122&
Private Enum SERVICE_CONTROL
SERVICE_CONTROL_STOP = 1&
SERVICE_CONTROL_PAUSE = 2&
SERVICE_CONTROL_CONTINUE = 3&
SERVICE_CONTROL_INTERROGATE = 4&
SERVICE_CONTROL_SHUTDOWN = 5&
End Enum
Public Enum SERVICE_STATE
SERVICE_STOPPED = &H1
SERVICE_START_PENDING = &H2
SERVICE_STOP_PENDING = &H3
SERVICE_RUNNING = &H4
SERVICE_CONTINUE_PENDING = &H5
SERVICE_PAUSE_PENDING = &H6
SERVICE_PAUSED = &H7
End Enum
Private Type SERVICE_STATUS
dwServiceType As Long
dwCurrentState As Long
dwControlsAccepted As Long
dwWin32ExitCode As Long
dwServiceSpecificExitCode As Long
dwCheckPoint As Long
dwWaitHint As Long
End Type
Private Type QUERY_SERVICE_CONFIG
dwServiceType As Long
dwStartType As Long
dwErrorControl As Long
lpBinaryPathName As Long
lpLoadOrderGroup As Long
dwTagId As Long
lpDependencies As Long
lpServiceStartName As Long
lpDisplayName As Long
End Type
Private Declare Function OpenSCManager _
Lib “advapi32” Alias “OpenSCManagerW” _
(ByVal lpMachineName As Long, ByVal lpDatabaseName As Long, _
ByVal dwDesiredAccess As Long) As Long
Private Declare Function CreateService _
Lib “advapi32” Alias “CreateServiceW” _
(ByVal hSCManager As Long, ByVal lpServiceName As Long, _
ByVal lpDisplayName As Long, ByVal dwDesiredAccess As Long, _
ByVal dwServiceType As Long, ByVal dwStartType As Long, _
ByVal dwErrorControl As Long, ByVal lpBinaryPathName As Long, _
ByVal lpLoadOrderGroup As Long, ByVal lpdwTagId As Long, _
ByVal lpDependencies As Long, ByVal lpServiceStartName As Long, _
ByVal lpPassword As Long) As Long
Private Declare Function DeleteService _
Lib “advapi32” (ByVal hService As Long) As Long
Private Declare Function CloseServiceHandle _
Lib “advapi32” (ByVal hSCObject As Long) As Long
Private Declare Function OpenService _
Lib “advapi32” Alias “OpenServiceW” _
(ByVal hSCManager As Long, ByVal lpServiceName As Long, _
ByVal dwDesiredAccess As Long) As Long ‘** Change Service_Name as needed
Private Declare Function QueryServiceConfig Lib “advapi32” _
Alias “QueryServiceConfigW” (ByVal hService As Long, _
lpServiceConfig As QUERY_SERVICE_CONFIG, _
ByVal cbBufSize As Long, pcbBytesNeeded As Long) As Long
Private Declare Function QueryServiceStatus Lib “advapi32” _
(ByVal hService As Long, lpServiceStatus As SERVICE_STATUS) As Long
Private Declare Function ControlService Lib “advapi32” _
(ByVal hService As Long, ByVal dwControl As SERVICE_CONTROL, _
lpServiceStatus As SERVICE_STATUS) As Long
Private Declare Function StartService Lib “advapi32” _
Alias “StartServiceW” (ByVal hService As Long, _
ByVal dwNumServiceArgs As Long, ByVal lpServiceArgVectors As Long) As Long
Private Declare Function ChangeServiceConfig2 Lib “advapi32” Alias “ChangeServiceConfig2W” (ByVal hService As Long, _
ByVal dwInfoLevel As Long, lpInfo As Any) As Long
Private Declare Function NetWkstaUserGetInfo Lib “Netapi32” (ByVal reserved As Any, ByVal Level As Long, lpBuffer As Any) As Long
Private Declare Function NetApiBufferFree Lib “Netapi32” (ByVal lpBuffer As Long) As Long
‘Private Declare Function lstrcpy Lib “kernel32” Alias “lstrcpyA” (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
‘Private Declare Function lstrlen Lib “kernel32” Alias “lstrlenA” (ByVal lpString As Any) As Long
Private Declare Sub CopyMemory Lib “kernel32” Alias “RtlMoveMemory” (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function lstrcpyW Lib “kernel32” (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
Private Declare Function lstrlenW Lib “kernel32” (ByVal lpString As Long) As Long
Private Const Service_Name As String = “SampleVB6Service”
Private Const Service_Display_Name As String = “Sample VB6 Service”
Private Const Service_File_Name As String = “SvSample.exe”
Private Const Service_Description As String = “A sample of service program written on Visual Basic 6.0.”
Public AppPath As String

在这里把自己注册成系统服务非常简单,只要把路径,服务名等一些参数修改,稍微许该一下form中的代码就可以从容的把自己注册为系统服务了.
点击下载此文件


金刀客博客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明VB程序设置为系统服务的几种办法
喜欢 (7)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到
(3)个小伙伴在吐槽
  1. aivb 附件中有实例的,你下载看看
    admin2009-11-19 15:37 回复
  2. 请问用你所说的第三种方法如何在form里写代码呢?有例子吗?谢谢。我是初学者
    aivb2009-11-19 12:51 回复
  3. 为什么vb6中用控件注册服务后,成功注册,启动方式:自动,但是当前状态是:已停止? 而且不能开机自启动啊。。。
    admin 于 2009-07-15 10:18 PM 回复
    这个得视具体情况了,我也没办法判断,我建议你用api来做可能更好
    ihavetosay2009-07-15 16:16 回复