接收同步和半同步事件通知

使用 SWbemServices.ExecQuery 请求所有现有事件。

以下代码示例演示如何查询日志中的事件。

Select * from Win32_NTLogEvent

有关详细信息,请参阅确定要接收的事件类型接收事件通知WQL(适用于 WMI 的 SQL)

SWbemServices.ExecNotificationQuery 的默认调用使用半同步通信。 默认情况下,为 iflags 参数设置了 wbemFlagForwardOnly 和 wbemFlagReturnImmediately 标志。 有关详细信息,请参阅调用方法

以下过程说明如何使用 VBScript 接收半同步事件通知。

在 VBScript 中接收半同步事件通知

  1. 针对要接收的事件类型创建查询。 有关详细信息,请参阅确定要接收的事件类型

  2. 如果你要请求 __InstanceCreationEvent 等事件的实例类型,请在查询中指明目标实例的类型,例如 Win32_LogicalDisk

  3. 如有必要,请在请求特定命名空间的将来 __NamespaceModificationEvent 实例时指定一个实例,例如命名空间的名称。

  4. 在查询中指定 Windows Management Instrumentation (WMI) 的轮询间隔,例如“WITHIN 10”– 每隔 10 秒轮询一次。 有关详细信息,请参阅 WITHIN 子句

  5. 使用查询调用 SWbemServices.ExecNotificationQuery

  6. 循环访问收到的集合。

以下示例演示如何监视在本地计算机上的软盘驱动器中插入和移除磁盘的操作。 该脚本请求软盘驱动器 Win32_LogicalDisk 实例的 __InstanceModificationEvent 实例,并每隔 10 秒轮询新实例。 此脚本是临时事件使用者的示例,它会持续运行到它在任务管理器中被停止或系统重启为止。 有关详细信息,请参阅接收应用程序持续运行期间发生的事件

Const FLOPPY_DISK = 2
Set colMonitoredDisks = GetObject("Winmgmts:").ExecNotificationQuery _
    ("Select * from __InstanceModificationEvent within 10 WHERE " _
        & "TargetInstance ISA 'Win32_LogicalDisk'")
i = 0
Do While i = 0
    Set strDiskChange = colMonitoredDisks.NextEvent
    If strDiskChange.TargetInstance.DriveType = FLOPPY_DISK Then
        If strDiskChange.TargetInstance.Size > 0 Then
            Wscript.Echo "A disk has been inserted" & _
                " into the floppy drive."
    Else
            Wscript.Echo "A disk has been removed" & _
                " from the floppy drive."
        End If
    End If
Loop

以下过程说明如何使用 C++ 接收半同步事件通知。

在 C++ 中接收半同步事件通知

  1. 通过调用 CoInitializeExCoInitializeSecurity 函数来设置应用程序。

    由于 WMI 基于 COM,因此调用 CoInitializeExCoInitializeSecurity 是 WMI 应用程序的必需步骤。 有关详细信息,请参阅创建 WMI 应用程序或脚本

  2. 确定要接收的事件类型。

    WMI 支持内在和外在事件。 内在事件是 WMI 预定义的事件。 外在事件是第三方提供程序定义的事件。 有关详细信息,请参阅确定要接收的事件类型

  3. 通过调用 IWbemServices::ExecNotificationQuery 方法进行注册以接收特定的事件类。

    使每个查询非常具体。 注册的目的是仅接收所需的通知。 不需要的通知会浪费处理和传递时间。

    可以设计一个事件使用者来接收多个事件。 例如,使用者可能需要通知特定设备类的实例修改事件和安全违规事件。 在这种情况下,使用者在收到实例修改事件时执行的任务对于这两个事件是不同的。 因此,使用者应该调用 IWbemServices::ExecNotificationQuery 来注册实例修改事件,然后再次调用 ExecNotificationQuery 来注册安全违规事件。

    ExecNotificationQuery 调用中,将 lFlags 参数设置为 WBEM_FLAG_RETURN_IMMEDIATELY 和 WBEM_FLAG_FORWARD_ONLY。 WBEM_FLAG_RETURN_IMMEDIATELY 标志请求半同步处理,WBEM_FLAG_FORWARD_ONLY 标志请求只进枚举器。 有关详细信息,请参阅调用方法。 ExecNotificationQuery 函数返回指向 IEnumWbemClassObject 接口的指针。

  4. 通过重复调用 IEnumWbemClassObject::Next 方法轮询已注册的事件通知。

  5. 完成后,释放指向 IEnumWbemClassObject 对象的枚举器。

    可以释放与注册关联的 IWbemServices 指针。 释放 IWbemServices 指针会导致 WMI 停止向所有关联的临时使用者传递事件。