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 を使用して非同期呼び出しを行うには

  1. WMI に接続し、SWbemServices オブジェクトを取得します。

    Set Service = GetObject("Winmgmts:")
    
  2. CreateObject または (Windows スクリプト ホスト 2.0 の場合のみ) events 属性が TRUE に設定された OBJECT タグを使って、オブジェクト シンクを作成します。

    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."
    

    このスクリプトを実行すると、最初のインスタンスが "Waiting for instances" というメッセージの前に返ったり、後で返ったりすることがあります。 これは非同期処理の性質です。 "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 セキュリティの維持