首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VBScript看门狗

VBScript看门狗
EN

Stack Overflow用户
提问于 2019-02-16 20:24:05
回答 2查看 523关注 0票数 0

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

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

我发现了一些使用订阅事件的.vbs online示例,我不认为这是我想要/需要的路径,因为脚本实际上需要持续运行,而不是只在修改特定文件时才异步运行。

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

到目前为止,我还没有找到一个很好的例子来分享。我一直在使用使用objWMIService.ExecNotificationQuery(Query)的其他示例,这些示例似乎很酷,因为使用的开销很少(本质上是异步的) --它似乎不符合我的需要,正如上面所描述的。

如果我必须分享我发现和玩过的东西..。好的..。下面是:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-17 11:37:09

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

代码语言:javascript
复制
Option Explicit

Const MONITOR_FILE = "c:\temp\test.txt"
Const MONITOR_LIMIT = 10

Dim wmi
    Set wmi  = GetObject( "winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2" )

Dim query
    query = "SELECT * FROM __InstanceOperationEvent WITHIN 1 " _ 
            & " WHERE TargetInstance ISA 'CIM_DataFile' " _ 
            & " AND   TargetInstance.Name='" & Replace(MONITOR_FILE, "\", "\\") & "'"

Dim colEvents
    Set colEvents = wmi.ExecNotificationQuery( query )

Dim currentEvent
    Do
        ' Flag value 
        Set currentEvent = Nothing
        ' Try to get the next event with a timeout limit
        ' If a timeout happens we need to catch raised error
        On Error Resume Next 
        Set currentEvent = colEvents.NextEvent( MONITOR_LIMIT * 1000 )
        On Error GoTo 0
        ' If there is not an event there was a timeout
        If currentEvent Is Nothing Then 
            Exit Do
        End If 
    Loop 

    WScript.Echo "File has not been changed for " & MONITOR_LIMIT & " seconds."
票数 0
EN

Stack Overflow用户

发布于 2019-02-17 11:09:57

事件观察者在事件发生时会做出反应。但是,您希望对没有发生的事件(即没有修改的文件)作出反应。出于明显的原因,您不能使用事件监视程序。

您需要的是检查文件最后修改日期的代码

代码语言:javascript
复制
path = "C:\Project\test.txt"

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

然后,如果时间戳超过x秒/分钟,则终止给定的进程。

代码语言:javascript
复制
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

但是,不支持您想要的每秒钟(或每2秒)运行任务的粒度。即使是这样,每秒产生一个新的进程对系统的性能并不是很好。您可以设置每日计划,然后指示任务计划程序在一天的时间内每5分钟重新运行任务。剩下的你需要在你的脚本中说明。

定义一个5分钟的超时,然后在循环中重新运行您的检查,直到超时过期:

代码语言:javascript
复制
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可以重用,所以不要在循环中反复定义它们,从而浪费资源。在脚本开始时只定义一次。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54727310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档