Tätigen eines asynchronen Anrufs mit VBScript

Durch einen asynchronen Aufruf einer WMI-Methode oder einer Anbietermethode kann ein Skript die Ausführung fortsetzen, während Objekte zu einem Objekt SWbemSink zurückkehren und von Methoden wie SWbemSink.OnObjectReady verarbeitet werden. Asynchrone Aufrufe werden jedoch nicht empfohlen, da die Daten möglicherweise nicht auf demselben Sicherheitsniveau zurückgegeben werden, wie der Aufruf erfolgt.

Wenn Sie asynchrone Senkenaufrufe wie SWbemSink.OnObjectReady zum Abrufen zurückgegebener Daten verwenden, können Sie den folgenden Registrierungswert festlegen.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault

Durch Festlegen dieses Registrierungswerts wird die Authentifizierung der an die Senke zurückgegebenen Datenobjekte sichergestellt. Wenn UnsecAppAccessControlDefault auf eins (1) festgelegt ist, führt WMI die Zugriffsüberprüfung der Datenrückgabe durch. Zugriffsprüfungen überprüfen, ob die Daten aus der richtigen Quelle stammen. Weitere Informationen finden Sie unter Festlegen der Sicherheit für einen asynchronen Aufruf.

Asynchrone Methoden mit Namen, die auf "Async_" enden, geben immer sofort nach dem Aufruf zurück, damit ein Programm weiterhin ausgeführt werden kann. Beispielsweise ist SWbemServices.ExecQuery synchron und blockiert die Ausführung, bis alle Objekte zurückgegeben werden. Die Methode SWbemServices.ExecQueryAsync ist die nicht blockierende asynchrone Version. Eine sicherere Möglichkeit, den Aufruf von SWbemServices.ExecQuery nicht blockieren zu lassen, besteht darin, den Aufruf halbsynchron durchzuführen. Weitere Informationen finden Sie unter Festlegen der Sicherheit für einen asynchronen Aufruf und Durchführen eines halbsynchronen Aufrufs mit VBScript.

Der Parameter iFlags für asynchrone Aufrufe ist standardmäßig immer null (0). Asynchrone Methoden stellen keine Sammlung SWbemObjectSet für die Senkenunterroutine bereit. Stattdessen empfängt die Ereignisunterroutine SWbemSink.OnObjectReady in Ihrem Skript oder Ihrer Anwendung jedes Objekt, wie es bereitgestellt wird.

Wenn der ursprüngliche asynchrone Aufruf abgeschlossen ist, ruft er das Ereignis SWbemSink.OnCompleted der Objektsenke auf und führt den Code aus, den Sie dort platzieren, um das Ergebnis des Aufrufs zu verarbeiten.

Hinweis

Eine Active Server Page (ASP) als Skripthost unterstützt keinen asynchronen Aufruf.

 

Im folgenden Verfahren wird beschrieben, wie Sie mithilfe von VBScript einen asynchronen Aufruf ausführen.

So tätigen Sie einen asynchronen Aufruf mit VBScript

  1. Stellen Sie eine Verbindung mit WMI her, und rufen Sie ein Objekt SWbemServices ab.

    Set Service = GetObject("Winmgmts:")
    
  2. Erstellen Sie die Objektsenke mithilfe von CreateObject oder (nur für Windows Script Host 2.0) mit dem OBJECT-Tag mit einem Ereignisattribute, das auf TRUE festgelegt ist.

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

    - oder -

    <OBJECT progid="WbemScripting.SWbemSink" ID="SINK" events="true"/>
    
  3. Erstellen Sie eine Unterroutine für jedes Ereignis, das ein asynchrones Ereignis auslösen kann. Diese Ereignisse werden als Methoden für SWbemObject definiert. WMI führt beispielsweise einen Rückruf an SWbemSink.OnObjectReady aus, da jede Instanz zurückgibt.

    Wenn Sie die Unterroutine erstellen, platzieren Sie Code in der Unterroutine, um jedes Ereignis beim Empfang zu behandeln.

    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
    

    Untersuchen Sie den vom Ereignis OnCompleted zurückgegebenen Parameter iHresult, um festzustellen, ob der asynchrone Aufruf erfolgreich ist oder ob ein Fehler aufgetreten ist. Bei erfolgreicher Ausführung ist der im Parameter iHresult übergebene Wert gleich null (0). Jeder andere Wert kann auf einen Fehler hinweisen, und Sie sollten die Werte im Fehlerobjekt überprüfen, das im Parameter objErrorObject zurückgegeben wird.

  4. Führen Sie einen asynchronen Aufruf aus, und übergeben Sie den Namen Ihrer Senke im Parameter objWbemSink .

    Service.InstancesOfAsync sink, "Win32_process"
    
  5. Führen Sie einen Aufruf aus, der verhindert, dass das Skript endet, bevor alle Ereignisse empfangen werden. Wenn Ihr Skript mit einer Bildschirmschnittstelle ausgeführt werden kann, können Sie dazu einfach einen Windows-Skripthostbefehl (Windows Script Host, WSH) Echo verwenden, der im folgenden Beispiel gezeigt wird.

    WScript.Echo "Waiting for instances."
    

    Wenn Sie dieses Skript ausführen, wird möglicherweise die erste Instanz vor der Meldung Warten auf Instanzen zurückgegeben, oder es wird möglicherweise danach angezeigt. Dies liegt an der Art der asynchronen Verarbeitung. Wenn Sie das Meldungsfeld Warten auf Instanzen zu früh schließen, werden möglicherweise nicht alle Instanzen angezeigt.

  6. Wenn Die Ergebnisse mehrerer asynchroner Aufrufe an dieselbe Senke zurückgegeben werden, speichern Sie alle erforderlichen Unterscheidungsdaten im Kontextparameter objWbemAsyncContext .

  7. Wenn Sie mit der Senke fertig sind, brechen Sie Ihren asynchronen Aufruf mit der Methode Cancel ab.

    objwbemsink.Cancel()
    

    Die Methode Cancel weist WSH an, alle asynchronen Aufrufe abzubrechen, die einem bestimmten Senkenobjekt zugeordnet sind. Daher können Sie separate Senken für asynchrone Vorgänge verwenden, die unabhängig sein müssen.

  8. Geben Sie das Senkenobjekt frei, indem Sie das Senkenobjekt an Nothing zuweisen.

    set objwbemsink= Nothing
    

Das folgende Codebeispiel zeigt eine asynchrone Abfrage für alle Instanzen von Win32_Process auf dem lokalen Computer. Eine halbsynchrone Version derselben Methode finden Sie unter Aufrufen einer Methode.

' 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

Aufrufen einer Methode

Aufrechterhalten der WMI-Sicherheit