VBScript看门狗

时间:2019-02-16 20:24:06

标签: vbscript

我正在尝试创建一个脚本,该脚本将查看本地计算机上的特定.txt文件,获取其DateLastModified属性,并将其与上次检查时的上一个/上一个值进行比较(循环中,每1个-2秒)。

循环(每秒运行一次)将增加一个计数器,如果计数器达到极限(例如10秒),则一段代码将执行“杀死/终止”特定进程/.exe的任务,即可能挂了,然后重新启动。

我已经找到一些使用订阅事件的不错的.vbs在线示例,我认为这不是我想要/不需要走的路,因为脚本实际上需要连续运行,而不是仅在以下情况下异步运行:特定文件已修改。

编辑:我正在寻找一种VBScript,它通过监视.txt文件的修改来提供“看门狗”功能。该脚本应每秒运行一次循环,以检查是否有修改,如果没有修改,则增加一个计数器。一旦计数器达到极限(10秒?),它将终止固定的进程(在VBScript中硬编码为参数),然后重新启动进程(在VBScript中作为参数的路径)。

到目前为止,我还没有找到一个很好的例子可以分享。我一直在研究其他利用objWMIService.ExecNotificationQuery(Query)的示例,该示例在使用很少的开销(本质上是异步的)上看起来很酷-似乎不符合我的如上所述。

如果我必须分享我发现的东西并一直在玩弄...好吧...这是

intInterval = "1"
strDrive = "C:"
strFolder = "\\Project\\"
strComputer = "."
intTmrVal = 0

Set objWMIService = GetObject( "winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" )

strQuery = "Select * From __InstanceOperationEvent" _
    & " Within " & intInterval _
    & " Where Targetinstance Isa 'CIM_DataFile'" _
    & " And TargetInstance.Name='C:\\Project\\test.txt'"

Set colEvents = objWMIService.ExecNotificationQuery(strQuery)

Do
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance

    Select Case objEvent.Path_.Class
        Case "__InstanceCreationEvent"
            WScript.Echo "Created: " & objTargetInst.Name
        Case "__InstanceDeletionEvent"
            WScript.Echo "Deleted: " & objTargetInst.Name
        Case "__InstanceModificationEvent"
            Set objPrevInst = objEvent.PreviousInstance

            For Each objProperty In objTargetInst.Properties_
                If objProperty.Value <> objPrevInst.Properties_(objProperty.Name) Then
                    WScript.Echo "Changed:        " & objTargetInst.Name
                    WScript.Echo "Property:       " & objProperty.Name
                    WScript.Echo "Previous value: " & objPrevInst.Properties_(objProperty.Name)
                    WScript.Echo "New value:      " & objProperty.Value
                End If
            Next
    End Select

    'Count how many times it has been modified // just playing with a counter
    If objEvent.TargetInstance.LastModified <> objEvent.PreviousInstance.LastModified Then
        intTmrVal = intTmrVal+1
        WScript.Echo "Changed:        " & intTmrVal & " times"
        WScript.Echo
    End If
Loop

2 个答案:

答案 0 :(得分:0)

事件观察者在事件发生时对其做出反应。但是,您想对未发生(即未修改的文件)事件做出反应。出于明显的原因,您不能为此使用事件观察器。

您需要的是用于检查文件的上次修改日期的代码

path = "C:\Project\test.txt"

Set fso = CreateObject("Scripting.FileSystemObject")
ts = fso.GetFile(path).DateLastModified

,如果该时间戳大于x秒/分钟,则杀死该进程

pname = "foo.exe"

wmi = GetObject("winmgmts://./root/cimv2")
qry = "SELECT * FROM Win32_Process WHERE Name='" & pname & "'"
If DateDiff("s", ts, Now) > 10 Then
    For Each p In wmi.ExecQuery(qry)
        p.Terminate
    Next
End If

但是,Windows Task Scheduler不支持您每秒(或每2秒)运行任务所需的粒度。即使这样做,每秒产生一个新进程对系统性能也不是一件好事。您可以设置每日计划,然后指示任务计划程序在一天的时间内每5分钟重新运行一次任务。您需要在脚本中说明的其余部分。

定义5分钟的超时时间,然后循环运行检查直到该超时时间结束:

interval = 2 'seconds
timeout  = 5 'minutes

endtime   = DateAdd("n", timeout, Now)
sleeptime = interval * 1000 'milliseconds
Do
    'check and process handling go here
    WScript.Sleep sleeptime
Loop Until Now >= endtime

由于fsowmi可以重复使用,因此不会在循环中反复定义资源,因此不会浪费资源。在脚本开头只定义一次。

答案 1 :(得分:0)

一种简单的方法是直接在WMI请求中为下一个事件设置超时

users,uid=1001,gid=1001,permissions
相关问题