使用 VBScript 进行异步调用
对 WMI 方法或提供程序方法进行异步调用允许脚本在对象返回到 SWbemSink 对象时继续执行,并由 SWbemSink.OnObjectReady 等方法处理。 但是,不建议使用异步调用,返回的数据可能与调用的安全级别不同。
使用 SWbemSink.OnObjectReady 等异步接收器调用获取返回的数据时,可以设置以下注册表值。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault
设置此注册表值可确保对返回到接收器的数据对象进行身份验证。 如果将“UnsecAppAccessControlDefault”设置为一 (1),则 WMI 对返回的数据执行访问检查。 访问检查验证数据是否来自正确的源。 有关详细信息,请参阅设置异步调用的安全性。
名称以“Async_”结尾的异步方法始终在调用后立即返回,以便程序可以继续执行。 例如,SWbemServices.ExecQuery 是同步方法,并阻止执行,直到返回所有对象。 SWbemServices.ExecQueryAsync 是非阻止异步方法。 较安全地对 SWbemServices.ExecQuery 进行非阻止调用的方法是半同步调用。 有关详细信息,请参阅设置异步调用的安全性和使用 VBScript 进行半同步调用。
异步调用的“iFlags”参数始终默认为零 (0) 。 异步方法不向接收器子例程提供 SWbemObjectSet 集合。 相反,脚本或应用程序中的 SWbemSink.OnObjectReady 事件子例程会接收提供的每个对象。
原始异步调用完成后,它会调用对象接收器的 SWbemSink.OnCompleted 事件,并执行放置在其中的代码来处理调用结果。
注意
作为脚本主机的 Active Server Page (ASP) 不支持异步调用。
以下过程介绍如何使用 VBScript 进行异步调用。
使用 VBScript 进行异步调用
连接到 WMI 并获取 SWbemServices 对象。
Set Service = GetObject("Winmgmts:")
使用 CreateObject 或事件属性设置为“TRUE”的 OBJECT 标记(仅限 Windows Script Host 2.0)。
Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
-或-
<OBJECT progid="WbemScripting.SWbemSink" ID="SINK" events="true"/>
为异步事件可以触发的每个事件创建子例程。 这些事件定义为 SWbemObject 上的方法。 例如,WMI 在返回每个实例时对 SWbemSink.OnObjectReady 进行回拨。
创建子例程时,请将代码放在子例程中,以便在收到每个事件时对其进行处理。
Sub SINK_OnCompleted( iHResult, objErrorObject, objAsyncContext ) WScript.Echo "Asynchronous operation is done." End Sub Sub SINK_OnObjectReady(objObject, objAsyncContext) WScript.Echo (objObject.Name) End Sub
检查 OnCompleted 事件返回的“iHresult”参数,以确定异步调用是否成功,或者是否发生错误。 如果成功,则“iHresult”参数中传递的值等于零 (0)。 任何其他值都可能指示错误,应检查“objErrorObject”参数中返回的错误对象中的值。
进行异步调用,并在“objWbemSink”参数中传递接收器的名称。
Service.InstancesOfAsync sink, "Win32_process"
进行调用,以防止脚本在接收所有事件之前结束。 如果可以使用屏幕界面运行脚本,则执行此操作的简单方法是使用 Windows Script Host (WSH)
Echo
命令,如以下示例所示。WScript.Echo "Waiting for instances."
执行此脚本时,可能会在“正在等待实例”消息之前看到第一个实例返回,也可能在之后。 这是异步处理的性质。 如果过早关闭“正在等待实例”消息框,则可能看不到所有实例。
如果有多个不同异步调用的结果返回到同一接收器,请将任何必要的区分数据存储在“objWbemAsyncContext”上下文参数中。
完成接收后,使用 Cancel 方法取消异步调用。
objwbemsink.Cancel()
Cancel 方法指示 WSH 取消与给定接收器对象关联的所有异步调用。 因此,可能需要对必须独立的异步操作使用单独的接收器。
通过将接收器对象分配给
Nothing
来释放接收器对象。set objwbemsink= Nothing
以下代码示例演示对本地计算机上所有 Win32_Process 实例的异步查询。 有关同一方法的半同步版本,请参阅调用方法。
' Create an object sink
set oSink = WScript.CreateObject("wbemscripting.swbemsink","sink_")
' Connect to WMI and the cimv2 namespace, and obtain
' an SWbemServices object
set oSvc = GetObject("winmgmts:root\cimv2")
bdone = false
' Query for all Win32_Process objects
osvc.ExecQueryAsync oSink, "SELECT Name FROM Win32_Process"
' Wait until all instances are returned.
' The bdone flag prevents the script from exiting until
' the sink.OnCompleted subroutine is executed when
' all the objects are returned.
while not bdone
wscript.sleep 1000
wend
' The sink subroutine to handle the OnObjectReady
' event. This is called as each object returns.
sub sink_OnObjectReady(oInst, octx)
WScript.Echo "Got Instance: " & oInst.Name
end sub
' The sink subroutine to handle the OnCompleted event.
' This is called when all the objects are returned.
' The oErr parameter obtains an SWbemLastError object,
' if available from the provider.
sub sink_OnCompleted(HResult, oErr, oCtx)
WScript.Echo "ExecQueryAsync completed"
bdone = true
end sub
相关主题