Erstellen eines asynchronen Aufrufs mit VBScript

Durch einen asynchronen Aufruf einer WMI-Methode oder Anbietermethode kann ein Skript die Ausführung fortsetzen, während Objekte an ein SWbemSink-Objekt zurückgegeben werden, und werden von Methoden wie SWbemSink.OnObjectReadyverarbeitet. Asynchrone Aufrufe werden jedoch nicht empfohlen, da die Daten möglicherweise nicht auf der gleichen Sicherheitsstufe wie der Aufruf zurückgegeben werden.

Wenn Sie asynchrone Senkenaufrufe wie SWbemSink.OnObjectReady verwenden, um zurückgegebene Daten abzurufen, können Sie den folgenden Registrierungswert festlegen.

HKEY _ LOKALE _ COMPUTERSOFTWARE \ \ Microsoft \ WBEM \ CIMOM \ UnsecAppAccessControlDefault

Durch Festlegen dieses Registrierungswerts wird die Authentifizierung der An die Senke zurückgegebenen Datenobjekte sichergestellt. Wenn UnsecAppAccessControlDefault auf 1 festgelegt ist, führt WMI eine Zugriffsüberprüfung der Datenrückgabe durch. Bei Zugriffsüberprüfungen wird überprüft, 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 von zurück, sodass die Ausführung eines Programms fortgesetzt werden kann. Beispielsweise ist SWbemServices.ExecQuery synchron und blockiert die Ausführung, bis alle Objekte zurückgegeben werden. Die SWbemServices.ExecQueryAsync-Methode ist die nicht blockierende asynchrone Version. Eine sicherere Möglichkeit zum Aufrufen der Nichtblockierung von SWbemServices.ExecQuery besteht darin, den Aufruf semisynchron zu machen. Weitere Informationen finden Sie unter Festlegen der Sicherheit für einen asynchronen Aufruf und Erstellen eines semisynchronen Aufrufs mit VBScript.

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

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

Hinweis

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

Das folgende Verfahren beschreibt, wie ein asynchroner Aufruf mithilfe von VBScript ausgeführt wird.

So erstellen Sie einen asynchronen Aufruf mit VBScript

  1. Verbinden zu WMI und abrufen ein SWbemServices-Objekt.

    Set Service = GetObject("Winmgmts:")
    
  2. Erstellen Sie die Objektsenke entweder mit CreateObject oder (nur für Windows Script Host 2.0) dem OBJECT-Tag, wobei ein Ereignisattribut 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 SWbemObjectdefiniert. Beispielsweise sendet WMI einen Rückruf an SWbemSink.OnObjectReady, wenn jede Instanz zurückgibt.

    Wenn Sie die Unterroutine erstellen, platzieren Sie Code in der Unterroutine, um jedes Ereignis zu behandeln, wenn es empfangen wird.

    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
    

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

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

    Service.InstancesOfAsync sink, "Win32_process"
    
  5. Nehmen Sie einen Aufruf vor, der verhindert, dass das Skript beendet wird, bevor alle Ereignisse empfangen werden. Wenn Ihr Skript mit einer Bildschirmschnittstelle ausgeführt werden kann, besteht eine einfache Möglichkeit darin, einen WSH-Befehl (Windows Script Host) zu Echo verwenden, wie im folgenden Beispiel gezeigt.

    WScript.Echo "Waiting for instances."
    

    Wenn Sie dieses Skript ausführen, wird möglicherweise die Rückgabe der ersten Instanz vor der Meldung Warten auf Instanzen oder danach angezeigt. Dies ist die 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 Sie Ergebnisse aus mehreren verschiedenen asynchronen Aufrufen erhalten, die an dieselbe Senke zurückgegeben werden, speichern Sie alle erforderlichen Unterscheidungsdaten im objWbemAsyncContext-Kontextparameter.

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

    objwbemsink.Cancel()
    

    Die Cancel-Methode weist WSH an, alle asynchronen Aufrufe abzubrechen, die einem bestimmten Senkenobjekt zugeordnet sind. Daher sollten 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 Nothing zuweisen.

    set objwbemsink= Nothing
    

Das folgende Codebeispiel zeigt eine asynchrone Abfrage für alle Instanzen des _ Win32-Prozesses auf dem lokalen Computer. Eine semisynchrone 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

Verwalten der WMI-Sicherheit