Vytvoření asynchronního volání pomocí jazyka C++
Aplikace WMI napsané v jazyce C++ mohou provádět asynchronní volání pomocí mnoha metod IWbemServices rozhraní COM. Doporučený postup volání metody rozhraní WMI nebo metody poskytovatele je použití polosynchronních volání, protože polosynchronní volání jsou bezpečnější než asynchronní volání. Další informace najdete v tématu Vytvoření polosynchronního volání pomocí jazyka C++ a Nastavení zabezpečení asynchronního volání.
Následující postup popisuje, jak provést asynchronní volání pomocí přijímacího bodu ve vašem procesu.
Provedení asynchronního volání pomocí jazyka C++
Implementujte rozhraní IWbemObjectSink.
Všechny aplikace, které provádějí asynchronní volání, musí implementovat IWbemObjectSink. Dočasní příjemci událostí rovněž implementují IWbemObjectSink pro příjem oznámení o událostech.
Přihlaste se k cílovému prostoru jmen služby WMI.
Aplikace musí vždy volat funkci COM CoInitializeSecurity během fáze inicializace. Pokud to neudělají před asynchronním voláním, WMI uvolní jímku aplikace bez dokončení asynchronního volání. Další informace naleznete v tématu Inicializace modelu COM pro aplikace rozhraní WMI.
Nastavte zabezpečení jímky.
Asynchronní volání vytvářejí celou řadu problémů se zabezpečením, se kterými se můžete zabývat, například povolení přístupu rozhraní WMI k vaší aplikaci. Další informace naleznete v tématu Nastavení zabezpečení asynchronního volání.
Proveďte asynchronní volání.
Metoda se okamžitě vrátí s úspěchu kódem WBEM_S_NO_ERROR. Aplikace může pokračovat s dalšími úlohami při čekání na dokončení operace. Rozhraní WMI hlásí zpět aplikaci voláním metod v implementaci aplikace IWbemObjectSink.
V případě potřeby pravidelně kontrolujte aktualizace vaší implementace.
Aplikace mohou přijímat oznámení o mezistavu nastavením parametru lFlags v asynchronním volání WBEM_FLAG_SEND_STATUS. WMI hlásí stav vašeho volání nastavením parametru lFlagsIWbemObjectSink na WBEM_STATUS_PROGRESS.
V případě potřeby můžete volání zrušit před dokončením zpracování WMI voláním metody IWbemServices::CancelCallAsync.
Metoda CancelAsyncCall zruší asynchronní zpracování okamžitým uvolněním ukazatele na rozhraní IWbemObjectSink a zaručuje, že ukazatel je uvolněn předtím, než se CancelAsyncCall vrátí.
Pokud používáte objekt obálky implementující rozhraní IUnsecured k hostování IWbemObjectSink, můžete najít některé další komplikace. Vzhledem k tomu, že aplikace musí předat stejný ukazatel na CancelAsyncCall, který byl předán v původním asynchronním volání, musí aplikace držet zabalený objekt, dokud není jasné, že zrušení není vyžadováno. Další informace naleznete v tématu Nastavení zabezpečení asynchronního volání.
Po dokončení vyčistěte ukazatele a ukončete aplikaci.
Rozhraní WMI poskytuje konečné volání stavu prostřednictvím metody SetStatus.
Poznámka
Po odeslání konečné aktualizace stavu WMI uvolní objektový dřez voláním metody Release pro třídu, která implementuje rozhraní IWbemObjectSink. V předchozím příkladu se jedná o metodu QuerySink::Release. Pokud chcete mít kontrolu nad životností objektu jímky, můžete jímku implementovat s počátečním počtem odkazů jednoho (1).
Pokud klientská aplikace předává stejné rozhraní jímky ve dvou různých překrývajících se asynchronních voláních, WMI nezaručuje pořadí zpětného volání. Klientská aplikace, která provádí překrývající se asynchronní volání, by měla předat různé objekty jímky nebo serializovat volání.
Následující příklad vyžaduje následující odkaz a #include příkazy.
#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>
Následující příklad popisuje, jak vytvořit asynchronní dotaz pomocí metody ExecQueryAsync, ale nevytvoří nastavení zabezpečení ani neuvolní objekt IWbemObjectSink. Další informace naleznete v tématu Nastavení zabezpečení asynchronního volání.
// 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;
}
Poznámka
Výše uvedený kód se nezkompiluje bez chyby, protože třída QuerySink nebyla definována. Další informace o QuerySinknaleznete v tématu IWbemObjectSink.