您好,SB。顺便说一下,感谢您对提问的措词:实际上,想在每次有人对特定注册表项进行更改时收到通知非常容易。如果您继续问“那么能够告诉我是谁进行了更改、进行了哪些更改?”,我们就会比较为难(稍后解释原因)。但您没有问这个问题,所以现在我们姑且当作没有提到此问题。
我们看一下监视 HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run 注册表项然后在每次更改该项时回显示一条消息的脚本:
strComputer = "."
Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/default")
Set colEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM RegistryKeyChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND " & _
"KeyPath='SOFTWARE//Microsoft//Windows//CurrentVersion//Run'")
Do
Set objLatestEvent = colEvents.NextEvent
Wscript.Echo Now & ": The registry has been modified."
Loop
首先,我们连接到 WMI 服务;更确切地说,我们连接到注册表事件类所在的 root/default 命名空间。然后,使用 ExecNotificationQuery 方法发出以下查询:
("SELECT * FROM RegistryKeyChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND " & _
"KeyPath='SOFTWARE//Microsoft//Windows//CurrentVersion//Run'")
我们目的就是每次创建 RegistryKeyChangeEvent 类实例时请求通知;您可能已经猜到,每次更改指定注册表项时(例如,添加新值或修改、删除现有值),都会创建一个此类实例。
听起来不错,但如何指定注册表项呢?这很简单;只需配置 RegistryKeyChangeEvent 类的以下两个属性:
| • |
Hive。这是注册表项所在的注册表配置单元(位置)。我们要监视 HKEY_LOCAL_MACHINE 中的某个项,所以将 Hive 属性值设置为 HKEY_LOCAL_MACHINE。若要监视 HKEY_CURRENT_USER 中的注册表项,则相应地设置该值。请注意,配置 Hive 属性时不必定义和使用常数;只键入注册表配置单元的实际名称即可。 |
| • |
KeyPath。这是配置单元中指向我们所需注册表项的路径。因为 / 是 WMI 中的保留字符,所以请注意,我们需要用第二个 / 来转义每个 /。因此,项路径 Software/Microsoft/Windows/CurrentVersion/Run 必须写为 Software//Microsoft//Windows//CurrentVersion//Run。 |
发出查询后,我们建立一个永远运行的 Do Loop,它将尽责地等待出现 RegistryKeyChangeEvent 类的下一个实例。为使脚本等待出现此类实例,我们使用此代码行:
Set objLatestEvent = colEvents.NextEvent
此代码行会使脚本“中断”,即脚本会暂停并等待下一事件发生(您知道,我们监视的事件是 RegistryKeyChangeEvent 类的新实例)。发生此类事件时,我们只需回显当前日期和时间以及已用某种方式修改注册表这一情况。然后我们再循环,等待发生下一个此类事件。(按 Ctrl+C 可退出循环并结束脚本。)
我们为什么不做得更具体些而是仅仅指出注册表已被以某种方式修改呢?主要是因为我们不能做得更具体:注册表事件提供程序不捕获诸如更改内容和更改人等的详细信息。我们可以确定其中某些信息,方法是获取注册表项的初始状态,然后当事件发生时,将新状态与初始状态进行比较。然后,我们就必须设置一个过程,以用于不断将注册表项的最新状态与其前一状态进行比较。但我们只能让您自己设置此过程。(当然,除非我们收到请求。毕竟,我们的使命是提供服务!)