Partager via


Déchargement d’un fournisseur

Une fois que WMI a terminé avec un fournisseur, il décharge le fournisseur de la mémoire. La raison principale pour laquelle WMI décharge un fournisseur consiste à conserver les ressources 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 quelle durée entre l’intervalle spécifié dans le contrôle du cache et deux fois cet intervalle pour que WMI désactive un fournisseur.

WMI décharge un fournisseur de l’une des façons suivantes :

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

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

Les sections suivantes sont décrites 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 non pur peut continuer à s’exécuter après que WMI appelle 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 trouverez ClearAfter dans les instances de classes dérivées de la classe système WMI __CacheControl dans l’espace de noms oot \r.

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 permet à un fournisseur de rester inactif en modifiant la propriété ClearAfter dans l’instance de contrôle de cache 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 pouvez modifier la propriété ClearAfter d’une instance __PropertyProviderCacheControl dans l’espace de noms oot \r.

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

Votre fournisseur peut avoir besoin de rester un client de WMI après avoir terminé les fonctions pour lesquelles il a été appelé. Par exemple, un fournisseur Push peut avoir besoin d’émettre des requêtes vers WMI. Pour plus d’informations, consultez Détermination de l’état Push ou Pull. Dans ce cas, la propriété Pure de l’instance de __Win32Provider qui représente le fournisseur doit être définie sur 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, consultez 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. Relâchez tous les pointeurs d’interface conservés 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 l’instance __Win32Provider associée 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 demandes de service. Par conséquent, ce type de fournisseur ne peut pas prendre le rôle d’une application cliente et WMI peut le 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 correctement votre fournisseur. Toutefois, vous pouvez rencontrer des situations où WMI n’est pas en mesure d’inciter les procédures de déchargement normales, par exemple lorsque l’utilisateur choisit d’arrêter le système. En utilisant un modèle de transaction 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 ni n'appelle le point d’entrée DllCanUnloadNow sur n’importe quel fournisseur en processus. De plus, si un fournisseur in-process est au milieu d’un appel de méthode au moment de l’arrêt, WMI peut éventuellement mettre fin au 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 maximum, WMI appelle DllMain uniquement.

Lorsque le système d’exploitation arrête WMI, le système libère automatiquement toutes les mémoires allouées à un fournisseur in-process. Le système d’exploitation ferme également la plupart des ressources détenues par le fournisseur, telles que les handles de fichiers, les handles de fenêtre, etc. Le fournisseur n’a pas besoin d’effectuer une action spécifique pour que cela se produise.

É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 disposant de fonctionnalités d’écriture peuvent vouloir implémenter un certain type de modèle de transaction pour permettre une restauration sécurisée après une arrêt brusque.

Même si le système d’exploitation peut libérer certaines ressources système générales, le système ne libère pas automatiquement toutes les ressources. Par exemple, le système d’exploitation ne peut pas libérer un socket ou une connexion de base de données. Au lieu de cela, le fournisseur peut avoir besoin de nettoyer 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 en dehors du 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 de terminaison sont plus importants que les performances peuvent être hors processus.

Si vous devez placer le 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 DLL que le système d’exploitation appelle lors du déchargement de la DLL. Le code de nettoyage peut être ajouté directement à 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 de la Base de connaissances Microsoft Q148791, « How to Provide Your Own DllMain in an MFC Regular DLL. » (Cette ressource peut ne pas être disponible dans certaines langues et pays ou régions.)

Vous pourriez alternativement placer le code de nettoyage dans le destructeur d’une classe globale. Pour plus d’informations, consultez Déchargement d’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 lors du déchargement DLL.

Voici une procédure de nettoyage simple qui peut s’adapter à 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 peuvent être accessibles de quelque manière que ce soit. En outre, vous ne pouvez pas effectuer d’appels COM dans n’importe quelle circonstance.

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

Sécurisation de votre fournisseur

Développement d’un fournisseur WMI