Effectuer 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 une méthode de fournisseur consiste à utiliser des appels semi-synchronisés, car les appels semi-synchronisés sont plus sécurisés que les appels asynchrones. Pour plus d’informations, voir Effectuer un appel semi-synchronisé avec C++ et Définir 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++

  1. 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 une notification d’événements.

  2. Connectez-vous à l’espace de noms WMI cible.

    Les applications doivent toujours appeler la fonction COM CoInitializeSecurity pendant la phase d’initialisation. S'ils ne le font pas avant d'effectuer un appel asynchrone, WMI libère le récepteur d'application sans effectuer l'appel asynchrone. Pour plus d’informations, voir Initialisation de COM pour une application WMI.

  3. Définissez la sécurité de votre récepteur.

    Les appels asynchrones créent divers problèmes de sécurité que vous devrez peut-être résoudre, par exemple en autorisant WMI à accéder à votre application. Pour plus d’informations, voir Définition de la sécurité sur un appel asynchrone.

  4. Effectuez l’appel asynchrone.

    La méthode retourne immédiatement avec le code de réussite WBEM_S_NO_ERROR. L’application peut effectuer d’autres tâches en attendant la fin de l’opération. WMI rend compte à l’application en appelant des méthodes dans l’implémentation IWbemObjectSink de votre application.

  5. Si nécessaire, vérifiez périodiquement les mises à jour de votre implémentation.

    Les applications peuvent recevoir une notification de statut intermédiaire en fixant le paramètre lFlags de l'appel asynchrone à WBEM_FLAG_SEND_STATUS. WMI signale la statut de votre appel en définissant le paramètre lFlags de IWbemObjectSinksur WBEM_STATUS_PROGRESS.

  6. Si nécessaire, vous pouvez annuler l’appel avant la fin du traitement de WMI en appelant la méthode IWbemServices::CancelCallAsync.

    La méthode CancelAsyncCall annule le traitement asynchrone en relâchant immédiatement le pointeur vers l’interface IWbemObjectSink et garantit que le pointeur est libéré avant le retour de CancelAsyncCall.

    Si vous utilisez un objet wrapper implémentant l’interface IUnsecured pour héberger IWbemObjectSink, vous pouvez rencontrer des complications supplémentaires. Étant donné que l’application doit passer le même pointeur vers CancelAsyncCall que celui qui a été passé dans l’appel asynchrone d’origine, l’application doit conserver l’objet wrapper jusqu’à ce qu’il soit clair que l’annulation n’est pas nécessaire. Pour plus d’informations, voir Définition de la sécurité sur un appel asynchrone.

  7. Lorsque vous avez terminé, nettoyez les pointeurs et arrêtez l'application.

    WMI fournit l'appel de statut final par le biais de la méthode SetStatus.

    Notes

    Après avoir envoyé la mise à jour de statut finale, 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 récepteur dans deux appels asynchrones qui se chevauchent, WMI ne garantit pas l’ordre du rappel. Une application client effectuant des appels asynchrones qui se chevauchent doit soit transmettre des objets récepteurs différents, soit sérialiser les appels.

L’exemple suivant nécessite les instructions de référence et de #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é ni ne libère l’objet IWbemObjectSink. Pour plus d’informations, voir 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, voir IWbemObjectSink.

 

Appel d’une méthode