本文介绍了监视驱动器.使用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 & "\root\CIMV2")
'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脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 06:29