使用 VBScript 進行非同步呼叫

WMI 方法提供者方法 進行非同步呼叫,可讓腳本在物件返回 SWbemSink 物件時繼續執行,並由 SWbemSink.OnObjectReady等方法處理。 不過,不建議使用非同步呼叫,因為資料可能不會以與呼叫相同的安全性層級傳回。

使用 SWbemSink.OnObjectReady 之類的非同步接收呼叫來取得傳回的資料時,您可以設定下列登錄值。

\ HKEY_LOCAL_MACHINE軟體\微軟\WBEM\CIMOM\UnsecAppAccessControlDefault

設定此登錄值可確保驗證傳回至接收的資料物件。 如果 UnsecAppAccessControlDefault 設定為一個 (1) ,則 WMI 會執行資料傳回的存取檢查。 存取檢查會確認資料來自正確的來源。 如需詳細資訊,請參閱 在非同步呼叫上設定安全性

名稱結尾為 「Async_」 的非同步方法一律會在呼叫之後立即傳回,讓程式可以繼續執行。 例如, SWbemServices.ExecQuery 是同步的,而且會封鎖執行,直到傳回所有物件為止。 SWbemServices.ExecQueryAsync方法是非封鎖非同步版本。 更安全的呼叫 SWbemServices.ExecQuery 非封鎖方式是 以半非同步方式進行呼叫。 如需詳細資訊,請參閱使用 VBScript 設定非同步呼叫進行半同步呼叫的安全性。

非同步呼叫的 iFlags 參數一律預設為零 (0) 。 非同步方法不會提供 SWbemObjectSet 集合給接收副程式。 相反地,腳本或應用程式中 的 SWbemSink.OnObjectReady 事件副程式會在提供時接收每個物件。

當原始非同步呼叫完成時,它會呼叫物件接收的 SWbemSink.OnCompleted 事件,並執行您放置該處以處理呼叫結果的程式碼。

注意

使用中伺服器頁面 (ASP) ,因為腳本主機不支援非同步呼叫。

 

下列程式描述如何使用 VBScript 進行非同步呼叫。

使用 VBScript 進行非同步呼叫

  1. 連線到 WMI 並取得 SWbemServices 物件。

    Set Service = GetObject("Winmgmts:")
    
  2. 使用 CreateObject 或 windows Script Host 2.0 的 (建立物件接收,只) OBJECT 標記,並將事件屬性設定為 TRUE

    Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
    

    -或-

    <OBJECT progid="WbemScripting.SWbemSink" ID="SINK" events="true"/>
    
  3. 為每個事件建立副程式,非同步事件可以觸發。 這些事件會定義為 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 參數所傳回之錯誤物件中的值。

  4. 進行非同步呼叫,並在 objWbemSink 參數中傳遞接收的名稱。

    Service.InstancesOfAsync sink, "Win32_process"
    
  5. 進行呼叫,以防止腳本在收到所有事件之前結束。 如果您的腳本可以使用螢幕介面執行,最簡單的方法是使用 Windows 腳本主機 (WSH) Echo 命令,如下列範例所示。

    WScript.Echo "Waiting for instances."
    

    當您執行此腳本時,您可能會在 等候實例 訊息之前看到第一個實例傳回,或者您可能會在之後看到它。 這是非同步處理的本質。 如果您太快關閉 [等候實例 ] 訊息方塊,則可能不會看到所有實例。

  6. 如果您有數個不同的非同步呼叫傳回相同接收的結果,請將任何必要的辨別資料儲存在 objWbemAsyncCoNtext 內容參數中。

  7. 完成接收時,請使用 Cancel 方法取消 非同步呼叫。

    objwbemsink.Cancel()
    

    Cancel方法會指示 WSH 取消與指定接收物件相關聯的所有非同步呼叫。 因此,您可能想要針對必須獨立之非同步作業使用不同的接收。

  8. 將接收物件指派給 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

呼叫方法

維護 WMI 安全性