Wykonywanie wywołania asynchronicznego za pomocą języka C++
Aplikacje WMI napisane w języku C++ mogą wykonywać wywołania asynchroniczne przy użyciu wielu metod interfejsu IWbemServices COM. Zalecaną procedurą wywoływania metody WMI lub metody dostawcy jest użycie wywołań semisynchronicznych, ponieważ wywołania semisynchroniczne są bezpieczniejsze niż wywołania asynchroniczne. Aby uzyskać więcej informacji, zobacz Wykonywanie wywołania pół-synchronicznego w C++ oraz Ustawianie zabezpieczeń dla wywołania asynchronicznego.
Poniższa procedura opisuje sposób wykonywania asynchronicznego wywołania przy użyciu odbiornika w procesie.
Aby wykonać wywołanie asynchroniczne przy użyciu języka C++
Zaimplementuj interfejs IWbemObjectSink.
Wszystkie aplikacje, które wykonują wywołania asynchroniczne, muszą implementować IWbemObjectSink. Odbiorcy tymczasowi zdarzeń implementują również IWbemObjectSink do odbierania powiadomień o zdarzeniach.
Zaloguj się do docelowej przestrzeni nazw WMI.
Aplikacje zawsze muszą wywoływać funkcję COM CoInitializeSecurity w fazie inicjowania. Jeśli nie zrobią tego przed wykonaniem wywołania asynchronicznego, usługa WMI zwalnia odbiornik aplikacji, nie kończąc wywołania asynchronicznego. Aby uzyskać więcej informacji, zobacz Inicjowanie modelu COM dla aplikacji WMI.
Ustaw zabezpieczenia dla umywalki.
Wywołania asynchroniczne stwarzają szereg problemów z zabezpieczeniami, z którymi możesz się zmierzyć, na przykład zezwolenie na dostęp usługi WMI do aplikacji. Aby uzyskać więcej informacji, zobacz Setting Security on an Asynchronous Call.
Wykonaj wywołanie asynchroniczne.
Metoda zwraca natychmiast kod powodzenia WBEM_S_NO_ERROR. Aplikacja może kontynuować wykonywanie innych zadań podczas oczekiwania na ukończenie operacji. Usługa WMI zgłasza aplikację z powrotem do aplikacji, wywołując metody w IWbemObjectSink implementacji aplikacji.
W razie potrzeby okresowo sprawdzaj implementację pod kątem aktualizacji.
Aplikacje mogą odbierać powiadomienia o stanie pośrednim, ustawiając parametr lFlags w wywołaniu asynchronicznym na WBEM_FLAG_SEND_STATUS. Usługa WMI zgłasza stan wywołania, ustawiając parametr lFlags obiektu IWbemObjectSink na WBEM_STATUS_PROGRESS.
W razie potrzeby możesz anulować wywołanie, zanim WMI zakończy przetwarzanie, wywołując metodę IWbemServices::CancelCallAsync.
Metoda CancelAsyncCall anuluje przetwarzanie asynchroniczne przez natychmiastowe zwolnienie wskaźnika do interfejsu IWbemObjectSink i gwarantuje, że wskaźnik zostanie zwolniony zanim CancelAsyncCall zwróci sterowanie.
Jeśli używasz obiektu otoki implementującego interfejs IUnsecured do obsługi IWbemObjectSink, może wystąpić kilka dodatkowych komplikacji. Ponieważ aplikacja musi przekazać ten sam wskaźnik do CancelAsyncCall, który został przekazany w oryginalnym wywołaniu asynchronicznym, aplikacja musi przechowywać obiekt opakowujący, dopóki nie stanie się jasne, że anulowanie nie jest wymagane. Aby uzyskać więcej informacji, zobacz Setting Security on an Asynchronous Call.
Po zakończeniu wyczyść wskaźniki i zamknij aplikację.
Usługa WMI udostępnia końcowe wywołanie stanu za pośrednictwem metody SetStatus.
Uwaga
Po wysłaniu ostatecznej aktualizacji stanu usługa WMI zwalnia odbiornik obiektu, wywołując metodę Release dla klasy, która implementuje interfejs IWbemObjectSink. W poprzednim przykładzie jest to metoda QuerySink::Release. Jeśli chcesz mieć kontrolę nad okresem istnienia obiektu ujścia, możesz zaimplementować ujście z początkową liczbą odwołań jedną (1).
Jeśli aplikacja kliencka przekazuje ten sam interfejs ujścia w dwóch różnych nakładających się wywołaniach asynchronicznych, usługa WMI nie gwarantuje kolejności wywołania zwrotnego. Aplikacja kliencka tworząca nakładające się wywołania asynchroniczne powinna przekazywać różne obiekty ujścia lub serializować wywołania.
Poniższy przykład wymaga następujących odwołań i instrukcji #include.
#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>
W poniższym przykładzie opisano sposób tworzenia asynchronicznego zapytania przy użyciu metody ExecQueryAsync, ale nie tworzy ustawień zabezpieczeń ani nie zwalnia obiektu IWbemObjectSink. Aby uzyskać więcej informacji, zobacz Ustawianie zabezpieczeń w wywołaniu asynchronicznym.
// 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;
}
Notatka
Powyższy kod nie kompiluje się bez błędu, ponieważ nie zdefiniowano klasy QuerySink. Aby uzyskać więcej informacji na temat QuerySink, zobacz IWbemObjectSink.
Tematy pokrewne