Scripting 监视驱动器。使用VB脚本

Scripting 监视驱动器。使用VB脚本,scripting,vbscript,wmi,wmi-query,wmi-service,Scripting,Vbscript,Wmi,Wmi Query,Wmi Service,我想使用VBScript监视驱动器中的文件更改。我有下面的代码。它适用于InstanceCreationEvent和InstanceDeleteEvent。但是InstanceModificationEvent没有发生。通过谷歌搜索,我知道我们需要使用CIM\u数据文件而不是CIM\u目录containsFile来监视实例修改事件。我不知道如何修改代码。有人能帮忙吗 仅供参考:一个脚本应该监视驱动器中的所有文件夹和子文件夹 PS:任何关于改进代码和性能的建议或其他想法都是欢迎的 我的代码: Di

我想使用VBScript监视驱动器中的文件更改。我有下面的代码。它适用于
InstanceCreationEvent
InstanceDeleteEvent
。但是
InstanceModificationEvent
没有发生。通过谷歌搜索,我知道我们需要使用
CIM\u数据文件
而不是
CIM\u目录containsFile
来监视
实例修改事件
。我不知道如何修改代码。有人能帮忙吗

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

PS:任何关于改进代码和性能的建议或其他想法都是欢迎的

我的代码:

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

监视整个文件系统以创建文件是不可行的。这将消耗系统资源,并可能严重影响系统运行。仅监视选定的文件夹。以下方面应起作用:

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
Const Interval=1
Set monitor=CreateMonitor(“C:\foo”)
做
设置evt=monitor.NextEvent()
选择案例evt.Path_u2;.Class
案例“_InstanceCreationEvent”:发送通知evt.TargetInstance
案例“\uu InstanceModificationEvent”:。。。
案例“\uuu InstanceDeleteEvent”:。。。
结束选择
环
函数CreateMonitor(路径)
设置wmi=GetObject(“winmgmts://./root/cimv2")
设置fso=CreateObject(“Scripting.FileSystemObject”)
路径=拆分(fso.GetAbsolutePathName(路径),“:”)
drv=路径(0)和“:”
dir=Replace(路径(1),“\”,“\”)
如果右(dir,2)“\\”则dir=dir&“\\”
query=“选择*FROM\uuu InstanceOperationEvent”&_
“在”&间隔&_
“其中Targetinstance ISA‘CIM_数据文件’”&_
“和TargetInstance.Drive=”&drv&“”&_
“和TargetInstance.Path='”&dir&'”
设置CreateMonitor=wmi.ExecutionQuery(查询)
端函数
子发送通知(tgtInst)
'发送通知
端接头

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

不要使用“C”驱动器。由于有很多文件夹,您将得到索引超出范围和其他异常。在USB设备中尝试。监视驱动器中的所有文件夹和子文件夹有何用途?如果有人创建新文档/文件,应向用户列表发送通知邮件。我同意。但这是我的要求。你能帮我解决实际问题吗?如何监视文件中的内容更改,即:如果文本文件被修改,则必须引发修改事件。请参阅更新的答案。当我测试它时,上面的代码工作得很好。如果它没有捕获到
\u InstanceModificationEvent
,您必须找出事件未引发的原因。请注意,脚本仅检查给定文件夹的事件。它不会检测子文件夹中的更改。