注册系统注册表事件

若要从系统注册表提供程序接收通知,必须有一个注册为临时事件使用者的管理应用程序。 大多数注册系统注册表提供程序的要求都与任何其他事件注册相同,但你还必须执行以下过程。

注册表提供程序为系统注册表中的事件提供事件类。 有关一般事件注册的详细信息,请参阅接收 WMI 事件

以下过程说明如何注册系统注册表事件。

注册系统注册表事件

  1. 调用通知查询方法。

    在脚本或 C++ 中,使用 SWbemServices.ExecNotificationQueryAsyncIWbemServices::ExecNotificationQueryAsync 等通知查询。 为 IWbemServices::ExecNotificationQueryAsync 的 bstrQuery 参数或脚本中的 strQuery 创建查询字符串。

  2. 确定要接收的事件类型并创建查询。

    下表列出了可以使用的注册表事件类。

    事件类 配置单元位置 说明
    RegistryEvent 空值
    注册表中的更改的抽象基类。
    RegistryTreeChangeEvent RootPath
    监视对项层次结构的更改。
    RegistryKeyChangeEvent KeyPath
    监视对单个项的更改。
    RegistryValueChangeEvent ValueName
    监视对单个值的更改。

    这些类有一个名为 Hive 的属性,用于标识要监视其更改的项的层次结构,例如 HKEY_LOCAL_MACHINE。

    RegistryEvent 或从其派生的类(例如 RegistryTreeChangeEvent)不支持对 HKEY_CLASSES_ROOT 和 HKEY_CURRENT_USER 配置单元进行更改。

  3. 为事件注册创建 WHERE 子句。

    系统注册表提供程序具有 WHERE 子句的特定规则。 有关详细信息,请参阅为注册表提供程序创建适当的 WHERE 子句。 有关创建 WHERE 子句的更多一般信息,请参阅使用 WQL 进行查询

  4. 确定使用者是否正在接收事件。

    系统注册表提供程序不保证传递所有发送的事件。 有关详细信息,请参阅接收注册表事件

以下 VBScript 代码示例演示如何检测 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft 配置单元或子树中的注册表更改。 这是一个用于演示目的的监视脚本,它在名为 Wscript.exe 的进程中运行,直到它在“任务管理器”中被终止、WMI 停止或操作系统重启。 该脚本使用对 SWbemServices.ExecNotificationQuery半同步调用。 有关半同步调用的详细信息,请参阅使用 VBScript 进行半同步调用

Set wmiServices = GetObject("winmgmts:root/default") 
Set colTreeChanges = wmiServices.ExecNotificationQuery _
    ("SELECT * FROM RegistryTreeChangeEvent " _
    & "WHERE Hive='HKEY_LOCAL_MACHINE' " _
    & "AND RootPath='SOFTWARE\\Microsoft'")

While (True)
   Set TreeChange = colTreeChanges.NextEvent
   TreeChange.GetObjectText_()
   Wscript.Echo  "Hive = " & TreeChange.Hive & VBNewLine _
      & "RootPath = "& TreeChange.RootPath _
      & TreeChange.GetObjectText_()      
Wend

以下 VBScript 代码示例演示如何通过注册注册表提供程序事件类型 RegistryKeyChangeEvent 来监视项值的更改。 该脚本调用异步方法 SWbemServices.ExecNotificationQueryAsync。 有关异步调用和安全性的详细信息,请参阅使用 VBScript 进行异步调用

以下脚本将无限期运行,直到计算机重启、WMI 停止或脚本停止。 若要手动停止脚本,请使用任务管理器来停止进程。 若要以编程方式停止它,请在 Win32_Process 类中使用 Terminate 方法。

strComputer = "."
Set objWMIServices = GetObject("winmgmts:root/default") 
Set wmiSink = WScript.CreateObject( _
    "WbemScripting.SWbemSink", "SINK_") 
Set ObjRegistry = GetObject("winmgmts:_
    {impersonationLevel = impersonate}!\\" _
    & strComputer & "\root\default:StdRegProv")

' Create a new key
strPath = "SOFTWARE\MyKey\MySubKey\"
Return = objRegistry.CreateKey(HKEY_LOCAL_MACHINE, strPath)

' Start listening for change in key
objWMIServices.ExecNotificationQueryAsync wmiSink, _ 
    "SELECT * FROM RegistryKeyChangeEvent " _ 
    & "WHERE Hive='HKEY_LOCAL_MACHINE' AND " _ 
    & "KeyPath='SOFTWARE\\MyKey\\MySubKey\\'" 
WScript.Echo "Listening for Registry Change Events..." 

While(True) 
    WScript.Sleep 1000
' You can use Regedit to make a change in the key 
' HKEY_LOCAL_MACHINE\SOFTWARE\MyKey\MySubKey\ 
'    to see an event generated.
Wend 

Sub SINK_OnObjectReady(EventObject, wmiAsyncContext) 
    WScript.Echo "Received Registry Change Event" & vbCrLf & _
      EventObject.GetObjectText_() 
End Sub