Déchargement d’un fournisseur

Lorsque WMI en a terminé avec un fournisseur, il le décharge de la mémoire. La principale raison pour laquelle WMI décharge un fournisseur est de préserver les ressources du système. Par conséquent, vous devez ajouter du code qui permet à WMI de décharger votre fournisseur de manière efficace. Il faut n’importe où entre l’intervalle spécifié dans le contrôle de cache et le double de cet intervalle pour que WMI décharge un fournisseur.

WMI décharge un fournisseur de l’une des manières suivantes :

  • Déchargez un fournisseur une fois que le fournisseur a terminé les tâches qui lui sont confiées.
  • Déchargez rapidement tous les fournisseurs lorsque l’utilisateur arrête le système. Notez que WMI décharge les fournisseurs en cours de traitement lorsque le service WMI est arrêté à partir de la ligne de commande.

Bien que le premier scénario soit plus courant, vous devez écrire votre fournisseur pour les deux possibilités.

Les sections suivantes sont abordées dans cette rubrique :

Déchargement d'un fournisseur inactif

WMI effectue les actions suivantes lorsqu’il décharge un fournisseur inactif :

  • Détermine si le fournisseur est inactif.

    WMI utilise la propriété ClearAfter pour déterminer la durée pendant laquelle un fournisseur peut rester inactif avant de décharger ce fournisseur. Pour plus d’informations, consultez Accès au temps d’inactivité d’un fournisseur.

  • Appelle la méthode Release du fournisseur.

    Si le fournisseur était un fournisseur pur, Release supprime complètement le fournisseur de la mémoire active. Toutefois, un fournisseur sans achat peut continuer à s’exécuter après l’appel de WMI Release.

Accès au temps d’inactivité d’un fournisseur

La durée minimale pendant laquelle un fournisseur reste actif est déterminée par la propriété ClearAfter . Vous pouvez trouver ClearAfter dans les instances de classes dérivées de la classe système WMI __CacheControl dans l’espace de noms \root.

La liste suivante décrit les classes dérivées de __CacheControl, qui contrôle le déchargement du fournisseur :

Vous pouvez modifier la durée minimale pendant laquelle WMI autorise un fournisseur à rester inactif en modifiant la propriété ClearAfter dans le contrôle de cache instance pour un type spécifique de fournisseur. Par exemple, pour limiter la durée pendant laquelle un fournisseur de propriétés peut rester inactif, vous devez modifier la propriété ClearAfter d’un __PropertyProviderCacheControl instance dans l’espace de noms \root.

Déchargement d’un fournisseur qui est également un client WMI

Votre fournisseur peut avoir besoin de rester client de WMI une fois qu’il a terminé les fonctions de fournisseur qu’il a été appelé à effectuer. Par exemple, un fournisseur push peut avoir besoin d’émettre des requêtes à WMI. Pour plus d’informations, consultez Détermination de l’état d’envoi ou d’extraction. Dans ce cas, la propriété Pure du __Win32Provider instance qui représente le fournisseur doit avoir la valeur TRUE. Si la propriété Pure est définie sur FALSE, le fournisseur se prépare à décharger en appelant IUnknown::Release sur tous les points d’interface en attente lorsque WMI appelle la méthode Release de son interface principale. Pour plus d'informations, voir la section Remarques dans __Win32Provider.

La procédure suivante décrit comment implémenter une méthode de mise en production pour l’interface principale de votre fournisseur.

Pour décharger un fournisseur

  1. Libérez tous les pointeurs d’interface retenus sur WMI lorsque WMI appelle la méthode Release de l’interface principale de votre fournisseur.

    En règle générale, un fournisseur contient des pointeurs vers les interfaces IWbemServices et IWbemContext fournies dans IWbemProviderInit::Initialize.

  2. Si la propriété Pure dans le __Win32Provider associé instance a la valeur FALSE, le fournisseur peut passer au rôle de l’application cliente après que WMI a appelé Release. Toutefois, WMI ne peut pas décharger un fournisseur qui fonctionne en tant que système client, ce qui augmente la surcharge du système.

    Un fournisseur avec Pure défini sur TRUE existe uniquement pour les requêtes de service. Par conséquent, ce type de fournisseur ne peut pas prendre le rôle d’une application cliente et WMI peut la décharger.

Déchargement d’un fournisseur pendant l’arrêt

Dans des circonstances normales, l’utilisation des instructions de déchargement d’un fournisseur qui est également un client WMI permet à WMI de décharger votre fournisseur correctement. Toutefois, vous pouvez rencontrer des situations où WMI ne peut pas déclencher les procédures de déchargement normales, par exemple lorsque l’utilisateur choisit d’arrêter le système. En utilisant un modèle transactionnel de stockage de données, en plus d’implémenter une bonne stratégie de nettoyage, vous pouvez vous assurer que votre fournisseur est correctement déchargé.

L’utilisateur peut arrêter WMI à tout moment. Dans ce cas, WMI ne décharge aucun fournisseur et n’appelle pas le point d’entrée DllCanUnloadNow sur un fournisseur in-process. En outre, si un fournisseur in-process se trouve au milieu d’un appel de méthode au moment de l’arrêt, WMI peut éventuellement arrêter le thread en cours d’exécution au milieu de l’appel. Dans ce cas, WMI n’appelle pas les routines qui gèrent normalement le nettoyage, comme un destructeur d’objet. Au plus, WMI appellera DllMain uniquement.

Lorsque le système d’exploitation arrête WMI, le système libère automatiquement toute la mémoire allouée à un fournisseur in-process. Le système d'exploitation ferme également la plupart des ressources détenues par le fournisseur, telles que les descripteurs de fichiers, les descripteurs de fenêtres, etc. Le fournisseur n’a pas besoin d’effectuer une action spécifique pour y parvenir.

Étant donné que WMI peut s’arrêter au milieu d’un appel, un fournisseur ne doit pas laisser les sources de données dans un état incohérent. Laisser vos données dans un état incohérent n’est pas un problème pour les fournisseurs en lecture seule. Toutefois, les fournisseurs dotés de fonctionnalités d’écriture peuvent souhaiter implémenter une sorte de modèle de transaction pour permettre une restauration sécurisée après un arrêt brusque.

Bien que le système d’exploitation puisse libérer certaines ressources système générales, il ne libère pas automatiquement toutes les ressources. Par exemple, le système d’exploitation ne peut pas libérer de socket ou de connexions aux base de données. Au lieu de cela, le fournisseur peut avoir besoin de propre manuellement ces ressources. Pour éviter ces problèmes, vous pouvez implémenter votre fournisseur hors processus ou ajouter du code de nettoyage.

La solution la plus simple consiste à implémenter votre fournisseur hors processus. Un fournisseur hors processus n’est pas tué lorsque WMI s’arrête, bien que WMI libère le fournisseur après un délai d’expiration COM. Les fournisseurs pour lesquels les problèmes de robustesse de nettoyage et d’arrêt sont plus importants que les performances peuvent être hors processus.

Si vous devez placer du code de nettoyage dans votre fournisseur, vous avez deux options. L’un des endroits où effectuer ce type de nettoyage est DllMain, la fonction de point d’entrée de DLL que le système d’exploitation appelle lors du déchargement de la DLL. Le code de nettoyage peut être ajouté directement dans DllMain, en l'exécutant en réponse à DLL_PROCESS_DETACH. L’implémentation du code de nettoyage dans DllMain peut être quelque peu difficile à organiser, en particulier dans les environnements de programmation tels que MFC ou ATL. Pour plus d’informations, consultez l’article Q148791 de la Base de connaissances Microsoft intitulé « Comment fournir votre propre DllMain dans une DLL régulière MFC. » (Cette ressource n’est peut-être pas disponible dans certaines langues et certains pays ou régions.)

Vous pouvez également placer le code de nettoyage dans le destructeur d’une classe globale. Pour plus d'informations, voir Décharger un fournisseur. Le système d’exploitation Windows n’alloue pas d’objets globaux sur le tas. Au lieu de cela, le système d’exploitation appelle les destructeurs pendant le déchargement de DLL.

La procédure suivante est une procédure de nettoyage simple qui pourrait être intégrée dans un objet global pour WMI.

class CMyCleanup
{
    ~CMyCleanup()
    {
        CloseHandle(m_hOpenFile);
        CloseDatabaseConnection(g_hDatabase);
    }
} g_Cleanup;

Il existe de nombreuses restrictions quant à ce qui peut être fait dans le code de nettoyage avec l’une ou l’autre approche. Par exemple, ni les threads ni les DLL qui ne sont pas implicitement liés ne sont accessibles de quelque manière que ce soit. En outre, vous ne pouvez en aucun cas passer des appels COM.

Définition des descripteurs de sécurité d’espace de noms

Sécurisation de votre fournisseur

Développement d’un fournisseur WMI