监控驱动.使用 VB 脚本 [英] Monitor Drive. Using VB Script

查看:19
本文介绍了监控驱动.使用 VB 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 VBScript 监视驱动器的文件更改.我有以下代码.它适用于 InstanceCreationEventInstanceDeletionEvent.但是 InstanceModificationEvent 没有发生.通过谷歌搜索,我知道我们需要使用 CIM_DataFile 而不是 CIM_DirectoryContainsFile 来监控 InstanceModificationEvent.我不确定如何修改代码.谁能帮忙.

I want to monitor a drive for file changes, using VBScript. I have the below code. It works fine for InstanceCreationEvent and InstanceDeletionEvent. But InstanceModificationEvent is not happening. From googling I got to know we need to use CIM_DataFile instead of CIM_DirectoryContainsFile to monitor InstanceModificationEvent. I am not sure how to modify the code. Can anyone help.

仅供参考:一个脚本应监控驱动器中的所有文件夹和子文件夹.

FYI: One script should monitor all the folders and subfolders in a drive.

PS:也欢迎任何改进代码和性能的建议或其他想法.

PS: Any suggestion to improve the code and performance or other ideas also welcome.

我的代码:

Dim arrFolders 
Dim strComputer 
Dim objWMIService 
Dim strFolder 
Dim strCommand 
Dim i 
Dim strQuery 

strChangeFile = "MonitorFolder_Log.txt"
strMailIDFile = "MonitorFolder_MailIDs.txt"

'Check if the log file exists, if not ceate a new file and exit the script. Restart the script again.
Set oFSO = CreateObject("Scripting.FileSystemObject")     
If not oFSO.FileExists(strChangeFile)  then
    'WScript.Echo "Change Log File Not Found. Creating new file..."
    Set oTxtFile = oFSO.CreateTextFile(strChangeFile)  
    WScript.Echo strChangeFile & " File Created." & vbCrLf & "Please restart the script." & vbCrLf
    WScript.Quit
End If

'Prompt for which drive should be monitored. If not a valid drive, then exit the script.
strDrive = InputBox("Enter the drive to monitor: " & vbCrLf & "E.g.: Input C to monitor C: drive.", "Monitor Folder - Oracle", "E")
If strDrive = "" then
    WScript.Echo "Not a valid drive. Terminating the script."
    WScript.Quit
End If

'Append ":" with the drive name.
strDrive = strDrive & ":"

'Read the mail IDs.
Set objFSOMailID = CreateObject("Scripting.FileSystemObject")
Set oTSMailID = objFSOMailID.OpenTextFile(strMailIDFile)
strMailIDsList = oTSMailID.ReadAll
oTSMailID.close
'WScript.Echo strMailIDsList

'Array to store the existing folder paths that should be monitored.
arrFolders = Array()
i = 0

Set FSO = CreateObject("Scripting.FileSystemObject")
ShowSubfolders FSO.GetFolder(strDrive)

Sub ShowSubFolders(Folder)
    For Each Subfolder in Folder.SubFolders
    i = i + 1
        folderPath = "" & Subfolder.Path & ""
    folderPath = Replace(folderPath ,"","\\")
    ReDim Preserve arrFolders(i)
    arrFolders(i) = folderPath
    'Wscript.Echo i & " " & arrFolders(i)
        ShowSubFolders Subfolder
    Next
End Sub 

'Set the first path to be the drive.
arrFolders(0) = strDrive & "\\"

'Use WMI query to get the file changes.
strComputer = "." 
Set objWMIService = GetObject("winmgmts:\" & strComputer & "
ootCIMV2") 
'Loop throught the array of folders setting up the monitor for Each 
i = 0 
For Each strFolder In arrFolders 
   'Create the event sink 
   'WScript.Echo "setup for folder: " & strFolder & vbLf
   strCommand = "Set EventSink" & i & " = WScript.CreateObject" & "(""WbemScripting.SWbemSink"", ""SINK" & i & "_"")" 
   ExecuteGlobal strCommand
   'Setup Notification 
   strQuery = "SELECT * " _
           & "FROM __InstanceOperationEvent " _
           & "WITHIN 1 " _
           & "WHERE Targetinstance ISA 'CIM_DirectoryContainsFile'" _
           & "  AND TargetInstance.GroupComponent = " & "'Win32_Directory.Name=""" & strFolder & """'"
   strCommand = "objWMIservice.ExecNotificationQueryAsync EventSink" & i & ", strQuery"
   ExecuteGlobal strCommand 
   'Create the OnObjectReady Sub 
   strCommand = "Sub SINK" & i & "_OnObjectReady(objObject, " &  "objAsyncContext)" & vbLf _
             & "  'Wscript.Echo objObject.TargetInstance.PartComponent" & vbLf _
             & "  SendNotification(objObject)" & vbLf _
             & "End Sub"
   'WScript.Echo strCommand 
   ExecuteGlobal strCommand 
   i = i + 1 
Next 

'Wait for events.
WScript.Echo "Waiting for events..." 
i = 0 
While (True) 
   Wscript.Sleep(1000) 
Wend


Function SendNotification(objObject)

    strEventType = objObject.Path_.Class
    strPartComp = Split(objObject.TargetInstance.PartComponent, "=")
    strFileName = Replace(strPartComp(1), "\", "")

    WScript.Echo strEventType
    WScript.Echo strFileName

    'Some more code to send mail and logs...

End Function

推荐答案

监视整个文件系统以创建文件是不可行的.会占用系统资源,严重影响系统运行.只监视选定的文件夹.以下应该有效:

Monitoring the entire filesystem for file creation is not feasible. It will eat up system resources and might severly affect system operation. Only ever monitor selected folders. The following should work:

Const Interval = 1

Set monitor = CreateMonitor("C:foo")
Do
  Set evt = monitor.NextEvent()
  Select Case evt.Path_.Class
    Case "__InstanceCreationEvent"     : SendNotification evt.TargetInstance
    Case "__InstanceModificationEvent" : ...
    Case "__InstanceDeletionEvent"     : ...
  End Select
Loop

Function CreateMonitor(path)
  Set wmi = GetObject("winmgmts://./root/cimv2")
  Set fso = CreateObject("Scripting.FileSystemObject")

  path = Split(fso.GetAbsolutePathName(path), ":")
  drv  = path(0) & ":"
  dir  = Replace(path(1), "", "\")
  If Right(dir, 2) <> "\" Then dir = dir & "\"

  query = "SELECT * FROM __InstanceOperationEvent" & _
          " WITHIN " & Interval & _
          " WHERE Targetinstance ISA 'CIM_DataFile'" & _
          " AND TargetInstance.Drive='" & drv & "'" & _
          " AND TargetInstance.Path='" & dir & "'"
  Set CreateMonitor = wmi.ExecNotificationQuery(query)
End Function

Sub SendNotification(tgtInst)
  'send notification
End Sub

您应该将不同文件夹的监视器作为单独的进程运行,因为NextEvent() 是一个阻塞操作.

You should run monitors for different folders as separate processes, because NextEvent() is a blocking operation.

这篇关于监控驱动.使用 VB 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆