Durchführen eines asynchronen Aufrufs mit C++

In C++ geschriebene WMI-Anwendungen können mit vielen Methoden der COM-Schnittstelle IWbemServices asynchrone Aufrufe tätigen. Das empfohlene Verfahren zum Aufrufen einer WMI-Methode oder einer Anbietermethode ist jedoch die Verwendung halbsynchroner Aufrufe, da halbsynchrone Aufrufe sicherer sind als asynchrone Aufrufe. Weitere Informationen finden Sie unter Durchführen eines halbsynchronen Aufrufs mit C++ und Festlegen der Sicherheit für einen asynchronen Aufruf.

Im folgenden Verfahren wird beschrieben, wie Sie mithilfe der Senke in Ihrem Prozess einen asynchronen Aufruf ausführen.

So führen Sie einen asynchronen Aufruf mit C++ durch

  1. Implementieren Sie die IWbemObjectSink-Schnittstelle.

    Alle Anwendungen, die asynchrone Aufrufe durchführen, müssen IWbemObjectSink implementieren. Vorübergehende Ereignisconsumer implementieren ebenfalls IWbemObjectSink, um Benachrichtigungen über Ereignisse zu erhalten.

  2. Melden Sie sich beim WMI-Zielnamespace an.

    Anwendungen müssen während der Initialisierungsphase immer die COM-Funktion CoInitializeSecurity aufrufen. Wenn sie dies nicht vor einem asynchronen Aufruf tun, gibt WMI die Anwendungssenke frei, ohne den asynchronen Aufruf abzuschließen. Weitere Informationen finden Sie unter Initialisieren von COM für eine WMI-Anwendung.

  3. Legen Sie die Sicherheit für Ihre Senke fest.

    Asynchrone Aufrufe erzeugen eine Reihe unterschiedlicher Sicherheitsprobleme, mit denen Sie möglicherweise umgehen müssen, z. B. das Zulassen des WMI-Zugriffs auf Ihre Anwendung. Weitere Informationen finden Sie unter Festlegen der Sicherheit für einen asynchronen Aufruf.

  4. Führen Sie den asynchronen Aufruf durch.

    Die Methode wird sofort mit dem Erfolgscode WBEM_S_NO_ERROR zurückgegeben. Die Anwendung kann mit anderen Aufgaben fortfahren, während sie auf den Abschluss des Vorgangs wartet. WMI meldet an die Anwendung zurück, indem Methoden in der IWbemObjectSink-Implementierung Ihrer Anwendung aufgerufen werden.

  5. Überprüfen Sie bei Bedarf Ihre Implementierung in regelmäßigen Abständen auf Updates.

    Anwendungen können Benachrichtigungen über einen Zwischenstatus erhalten, indem Sie den lFlags-Parameter in dem asynchronen Aufruf auf WBEM_FLAG_SEND_STATUS festlegen. WMI meldet die status Ihres Aufrufs, indem der lFlags-Parameter von IWbemObjectSink auf WBEM_STATUS_PROGRESS festgelegt wird.

  6. Bei Bedarf können Sie den Aufruf abbrechen, bevor WMI die Verarbeitung beendet, indem Sie die IWbemServices::CancelCallAsync-Methode aufrufen.

    Die CancelAsyncCall-Methode bricht die asynchrone Verarbeitung durch sofortiges Freigeben des Zeigers auf die IWbemObjectSink-Schnittstelle ab und garantiert, dass der Zeiger vor der Rückgabe von CancelAsyncCall freigegeben wird.

    Wenn Sie ein Wrapperobjekt verwenden, das die IUnsecured-Schnittstelle zum Hosten von IWbemObjectSink implementiert, können einige zusätzliche Komplikationen auftreten. Da die Anwendung denselben Zeiger auf CancelAsyncCall übergeben muss, der in dem ursprünglichen asynchronen Aufruf übergeben wurde, muss die Anwendung das Wrapperobjekt so lange behalten, bis klar wird, dass ein Abbruch nicht erforderlich ist. Weitere Informationen finden Sie unter Festlegen der Sicherheit für einen asynchronen Aufruf.

  7. Wenn Sie fertig sind, bereinigen Sie die Zeiger, und fahren Sie die Anwendung herunter.

    WMI stellt den letzten Statusaufruf über die SetStatus-Methode bereit.

    Hinweis

    Nach dem Senden der endgültigen Satusaktualisierung gibt WMI die Objektsenke frei, indem die Release-Methode für die Klasse aufgerufen wird, die die IWbemObjectSink-Schnittstelle implementiert. Im vorherigen Beispiel ist dies die QuerySink::Release-Methode. Wenn Sie die Lebensdauer des Senkenobjekts steuern möchten, können Sie die Senke mit einer anfänglichen Verweisanzahl von eins (1) implementieren.

     

    Wenn eine Clientanwendung dieselbe Senkenschnittstelle in zwei verschiedenen überlappenden asynchronen Aufrufen übergibt, garantiert WMI nicht die Reihenfolge des Rückrufs. Eine Clientanwendung, die überlappende asynchrone Aufrufe durchführt, sollte entweder verschiedene Senkenobjekte übergeben oder die Aufrufe serialisieren.

Im folgenden Beispiel sind die folgenden Verweise und #include-Anweisungen erforderlich.

#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>

Im folgenden Beispiel wird beschrieben, wie Sie eine asynchrone Abfrage mit der ExecQueryAsync-Methode durchführen, aber keine Sicherheitseinstellungen erstellen oder das IWbemObjectSink-Objekt freigeben. Weitere Informationen finden Sie unter Festlegen der Sicherheit für einen asynchronen Aufruf.

// Set input parameters to ExecQueryAsync.
BSTR QueryLang = SysAllocString(L"WQL");
BSTR Query = SysAllocString(L"SELECT * FROM MyClass");

// Create IWbemObjectSink object and set pointer.
QuerySink *pSink = new QuerySink;

IWbemServices* pSvc = 0;

// Call ExecQueryAsync.
HRESULT hRes = pSvc->ExecQueryAsync(QueryLang, 
                                    Query, 
                                    0, 
                                    NULL, 
                                    pSink);

// Check for errors.
if (hRes)
{
    printf("ExecQueryAsync failed with = 0x%X\n", hRes);
    SysFreeString(QueryLang);
    SysFreeString(Query);
    delete pSink;    
    return ERROR;
}

Hinweis

Der obige Code wird nicht ohne Fehler kompiliert, da die QuerySink-Klasse nicht definiert wurde. Weitere Informationen zu QuerySink finden Sie unter IWbemObjectSink.

 

Aufrufen einer Methode