Windows服务意外停止的对策

2009-07-02 08:36刘德军
新媒体研究 2009年10期
关键词:服务对策

刘德军

[摘要]针对Windows服务在运行过程中出现的意外停止的情况下实现无人值守定时检测服务状态,在服务停止后能自动启动服务。

[关键词]服务 意外停止 对策

中图分类号:TP3文献标识码:A文章编号:1671-7597(2009)0520032-02

一、前言

系统服务,是指执行指定系统功能的程序、例程或进程,以便支持其他程序,尤其是低层(接近硬件)程序,它是Windows系统的一个重要组成部分。

我院在做医院管理系统与医疗保险系统接口过程中使用到一个外加进系统的医保服务,但该服务在实际使用过程中经常出现服务不定时的意外停止,该服务的停止必然导致门诊住院医保病员的就诊不能正常进行,也给计算机中心的管理带来了很大的挑战,每次服务停止后都必须在服务器上用手工执行启动后才能恢复正常,为恢复该服务必须到机房手工处理,有时甚至在深夜。针对这一情况,如何才能在无人值守的情况下实现对该服务做监视和启动处理操作呢?经过多次摸索,终于成功地利用VB的API函数及系统的计划任务配合实现在无人值守情况下服务的

自动监视和服务停止后的自动启动。

二、方法简介

要实现对停止的服务重新启动,需要做到以下几个功能:

1.定时处理:利用系统的任务计划指定程序定时执行一次,执行处理完成后直接退出程序。

2.检测服务状态及重新启动服务:利用API函数构建的类模块实现对系统的服务状态进行服务状态的检测及停止状态下的再启动操作。

3.文件的读写功能:用API函数实现对配置文件的读取,用write函数实现将启动服务事件以追加方式写入到历史

文件中。

三、程序实现

(一)准备工作

新建一个标准工程,名称为[服务类],在工程中创建一个窗体,名称为[frmService];在工程资源管理器中新建一个模块,名称为[mdlService];在工程资源管理器中新建一个类模块,名称为[clsService]。如图1所示。

(二)程序代码

1.窗体代码

Option Explicit

Private Sub Form_Load()

iniPath = App.Path + "service.ini"

Dim mySrv As New clsService

Dim tService As String

'取需处理的服务

tService = GetFromINI("需监控服务", "名称", iniPath)

mySrv.Name = tService

'当前服务状态,如处理停止状态则做启动处理,否则退出程序

If mySrv.GetServiceStatus = SERVICE_STOPPED Then

'如启动服务正常,则写入历史文件中备查

If mySrv.StartNTService = 0 Then

Open App.Path + "服务历史.txt" For Append Shared As #1

Write #1, Format(Now, "yyyy-mm-dd hh:mm:ss") & "-" & tService & "服务意外停止,已重新执行了启动。"

Close #1

End If

End If

End

End Sub

2.模块代码

Option Explicit

Public iniPath As String

Public ServiceName As String

Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, lpKeyName As Any, ByVal lpDefault As String, ByVal lpRetunedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Public Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long

'取配置文件参数

Public Function GetFromINI(AppName As String, KeyName As String, FileName As String) As String

Dim RetStr As String

RetStr = String(255, Chr(0))

GetFromINI = Left(RetStr, GetPrivateProfileString(AppName, ByVal KeyName, "", RetStr, Len(RetStr), FileName))

End Function

3.类模块代码

Option Explicit

Private Const SC_MANAGER_CONNECT = &H1&

Private Const SERVICE_QUERY_STATUS = &H4&

Private Const SERVICE_START = &H10&

Public Enum SERVICE_START_TYPE

SERVICE_AUTO_START = 2&

SERVICE_DEMAND_START = 3&

SERVICE_DISABLED = &H4

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 Declare Function OpenSCManager Lib "advapi32" Alias "OpenSCManagerW" _

(ByVal lpMachineName As Long, ByVal lpDatabaseName As Long, _

ByVal dwDesiredAccess 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

Private Declare Function QueryServiceStatus Lib "advapi32" (ByVal hService _

As Long, lpServiceStatus As SERVICE_STATUS) As Long

Private Declare Function CloseServiceHandle Lib "advapi32" _

(ByVal hSCObject As Long) 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 Service_Name As String

'查询服务运行状态,4运行,1停止

Public Function GetServiceStatus() As SERVICE_STATE

Dim hSCManager As Long, hService As Long, Status As SERVICE_STATUS

hSCManager = OpenSCManager(0&, 0&, SC_MANAGER_CONNECT)

If hSCManager Then

hService = OpenService(hSCManager, StrPtr(Service_Name), SERVICE_QUERY_STATUS)

If hService Then

If QueryServiceStatus(hService, Status) Then

GetServiceStatus = Status.dwCurrentState

End If

CloseServiceHandle hService

End If

CloseServiceHandle hSCManager

End If

End Function

'开始服务

Public Function StartNTService() As Long

Dim hSCManager As Long, hService As Long

hSCManager = OpenSCManager(0&, 0&, SC_MANAGER_CONNECT)

If hSCManager Then

hService = OpenService(hSCManager, StrPtr(Service_Name), SERVICE_START)

If hService Then

If StartService(hService, 0, 0) = 0 Then

StartNTService = Err.LastDllError

End If

CloseServiceHandle hService

Else

StartNTService = Err.LastDllError

End If

CloseServiceHandle hSCManager

Else

StartNTService = Err.LastDllError

End If

End Function

'服务名称

Public Property Let Name(ByVal sSrvName As String)

Service_Name = sSrvName

End Property

(三)文件处理

新建一文本文件,改名为[Service.ini],且[Service.ini]要与[服务类.exe]文件放在同一个目录下,打开[Service.ini]文件在其中输入如下内容(注:此处用Alerter代替):

[需监控服务]

名称=Alerter

(四)任务计划处理

在“控制面板”中的“任务计划”中添加该可执行文件[服务类.exe]即可,按提示设定完成后,再在新增的任务计划中选择“高级计划选项”中选择“重复任务”,指定每隔多长时间即运行一次即可。若业务要求响应快,时间间隔就小一些,否则就长一些,时间间隔可根据需要自定。

四、编程后记

通过上述程序,能自动实现服务意外停止后的启动功能。该软件在Windows XP+VB6(SP6)环境下调试运行通运行。

猜你喜欢
服务对策
LabVIEW下的模拟电路实验教学创新对策
提高中小学音乐欣赏教学质量对策探讨
“深度伪造”中个人隐私的保护:风险与对策
集成创新发挥优势 自主研发服务造纸
走,找对策去!
我国货币错配的现状及对策
采掘服务个股表现
溶解度计算错误种种和对策
两则跟服务有关的故事
读者反馈 订阅服务