Exécution d’un appel asynchrone avec C++
Les applications WMI écrites en C++ peuvent effectuer des appels asynchrones à l’aide de nombreuses méthodes de l’interface com IWbemServices . Toutefois, la procédure recommandée pour appeler une méthode WMI ou un fournisseur consiste à utiliser des appels semi-synchrones, car les appels semi-synchrones sont plus sûrs que les appels asynchrones. Pour plus d’informations, consultez création d’un appel semi-synchrone avec C++ et définition de la sécurité sur un appel asynchrone.
La procédure suivante décrit comment effectuer un appel asynchrone à l’aide du récepteur dans votre processus.
Pour effectuer un appel asynchrone à l’aide de C++
Implémentez l’interface IWbemObjectSink .
Toutes les applications qui effectuent des appels asynchrones doivent implémenter IWbemObjectSink. Les consommateurs d’événements temporaires implémentent également IWbemObjectSink pour recevoir des notifications d’événements.
Connectez-vous à l’espace de noms WMI cible.
Les applications doivent toujours appeler la fonction COM CoInitializeSecurity lors de la phase d’initialisation. Si ce n’est pas le cas avant d’effectuer un appel asynchrone, WMI libère le récepteur d’application sans terminer l’appel asynchrone. Pour plus d’informations, consultez initialisation de com pour une application WMI.
Définissez la sécurité de votre récepteur.
Les appels asynchrones créent un grand nombre de problèmes de sécurité que vous devrez peut-être gérer, par exemple, en autorisant l’accès WMI à votre application. Pour plus d’informations, consultez définition de la sécurité sur un appel asynchrone.
Effectuez l’appel asynchrone.
La méthode est retournée immédiatement avec l’absence de code de réussite des _ _ _ Erreurs WBEM . L’application peut effectuer d’autres tâches en attendant que l’opération se termine. WMI renvoie à l’application en appelant des méthodes dans l’implémentation IWbemObjectSink de votre application.
Si nécessaire, vérifiez régulièrement votre mise en œuvre des mises à jour.
Les applications peuvent recevoir une notification d’état intermédiaire en définissant le paramètre lFlags dans l’appel asynchrone de l’état d’envoi de l' _ indicateur _ _ WBEM. WMI signale l’état de votre appel en définissant le paramètre lFlags de IWbemObjectSink sur WBEM _ Status _ Progress.
Si nécessaire, vous pouvez annuler l’appel avant que WMI termine le traitement en appelant la méthode IWbemServices :: CancelCallAsync .
La méthode CancelAsyncCall annule le traitement asynchrone en libérant immédiatement le pointeur vers l’interface IWbemObjectSink et garantit que le pointeur est libéré avant que CancelAsyncCall retourne.
Si vous utilisez un objet wrapper qui implémente l’interface IUnsecured pour héberger des IWbemObjectSink, vous risquez de rencontrer des complications supplémentaires. Étant donné que l’application doit passer le même pointeur à CancelAsyncCall qui a été passé dans l’appel asynchrone d’origine, l’application doit conserver l’objet de wrapper jusqu’à ce qu’il soit clair que l’annulation n’est pas nécessaire. Pour plus d’informations, consultez définition de la sécurité sur un appel asynchrone.
Lorsque vous avez terminé, nettoyez les pointeurs et arrêtez l’application.
WMI fournit l’appel d’état final par le biais de la méthode SetStatus .
Notes
Après l’envoi de la dernière mise à jour d’État, WMI libère le récepteur d’objets en appelant la méthode Release pour la classe qui implémente l’interface IWbemObjectSink . Dans l’exemple précédent, il s’agit de la méthode QuerySink :: Release . Si vous souhaitez contrôler la durée de vie de l’objet récepteur, vous pouvez implémenter le récepteur avec un nombre de références initial de un (1).
Si une application cliente passe la même interface de récepteur dans deux appels asynchrones différents qui se chevauchent, WMI ne garantit pas l’ordre du rappel. Une application cliente qui effectue des appels asynchrones qui se chevauchent doit passer différents objets récepteur ou sérialiser les appels.
L’exemple suivant requiert la référence et les # instructions include suivantes.
#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>
L’exemple suivant décrit comment créer une requête asynchrone à l’aide de la méthode ExecQueryAsync , mais ne crée pas de paramètres de sécurité ou ne libère pas l’objet IWbemObjectSink . Pour plus d’informations, consultez définition de la sécurité sur un appel asynchrone.
// 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;
}
Notes
Le code ci-dessus ne se compile pas sans erreur, car la classe QuerySink n’a pas été définie. Pour plus d’informations sur QuerySink, consultez IWbemObjectSink.