现在我们开始考虑监控进程,刚开始我考虑重用我们前面的后台进程的设计,让ASP页面去做这个工作,但是考虑到IIS没有权限执行重启Windows服务这么核心的操作,所以只能将这个工作放在vbs中去做了。
还好我们的vbs都是通过添加到服务的方式,用SYSTEM用户运行的,如果是一般用户的话,可能还是没有权限。经过试验,我写了一个TaskMaster.wsf
<?xml version="1.0" encoding="UTF-8"?>
<job id="KeepAlive">
<script language="VBScript" src="../inc/log.vbs" />
<script language="VBScript" src="../inc/database.conn.vbs" />
<script language="VBScript" src="../inc/database.vbs" />
<script language="VBScript" src="master.vbs" />
</job>
因为用到了连接数据库,所以我做了一个数据库的类,因为是后台运行可能需要输出log文件,便于找错误,我又做了一个log类,然后把vbs代码单独写到一个vbs文件中,命名master.vbs。回头有空我再把log和database两个类也贴出来。
先继续我们的master工作,master.vbs:
set allTasks = CreateObject("Scripting.Dictionary")
set serviceName = CreateObject("Scripting.Dictionary")
'这里设置需要检查的任务、设置间隔的时间、Windows服务名
allTasks("helloworld") = 10*1000
serviceName("helloworld") = "网站自动任务一"
do while true
for each taskId in allTasks
'这里的SQL执行用到了db这个CDatabase类的全局实例,这个类有点麻烦,下次再贴。
'这句SQL的意思是看表里有没有名为taskId且与当前时间间隔小于任务时间间隔的日志
sql = "select top 1 * from logAutoTasks where taskId='"&taskId&"' and datediff(ss,logTime,getDate())<"&allTasks(taskId)&" order by logTime desc;"
set rs = db.OpenR(sql)
logTime = ""
if not rs.eof then logTime = rs("logTime")
rs.close
if logTime="" then
'在间隔时间内找不到运行的记录,说明超时了或者程序没启动
Set oShell = CreateObject("WScript.shell")
commandLine = "net stop """&serviceName(taskId)&""""
oShell.Exec(commandLine)
commandLine = "net start """&serviceName(taskId)&""""
oShell.Exec(commandLine)
Set oShell = Nothing
end if
next
WScript.Sleep 20*60*1000
loop
嗯,20分钟执行一次检查差不多。
到这里,如果我们手工去点是没有权限的(当然如果你用Administrator登录计算机的不算),也得把他加到Windows服务中去。用前面提到的instsrv.exe和srvany.exe将TaskMaster.wsf加入服务,取个名字叫”网站自动任务master”吧,然后启动它,并试试停掉其他任务,过20分钟,它就会自动将任务服务重新启动起来了!
最后作为总结工作备忘,画一张图吧:
谢谢阅读。