Compartir a través de


Retirar un proveedor

Una vez que WMI haya terminado con un proveedor, descarga el proveedor de la memoria. La principal razón por la que WMI descarga un proveedor es conservar los recursos del sistema. Por lo tanto, debe agregar código que permita a WMI descargar su proveedor de forma eficaz. Se tarda desde el intervalo especificado en el control de caché hasta el doble de ese intervalo para que WMI descargue un proveedor.

WMI descarga un proveedor de una de las maneras siguientes:

  • Descargue un proveedor después de que el proveedor finalice las tareas que se le han proporcionado.
  • Descarga rápidamente todos los proveedores cuando el usuario cierra el sistema. Tenga en cuenta que WMI descarga proveedores en proceso cuando el servicio WMI se cierra desde la línea de comandos.

Aunque el primer escenario es más común, debe escribir a su proveedor para ambas posibilidades.

En este tema se describen las secciones siguientes:

Descargar un proveedor inactivo

WMI realiza las siguientes acciones cuando descarga un proveedor inactivo:

  • Determina si el proveedor está inactivo.

    WMI usa la propiedad ClearAfter para determinar cuánto tiempo puede permanecer inactivo un proveedor antes de descargar ese proveedor. Para obtener más información, consulte Acceso al tiempo de inactividad de un proveedor.

  • Llama al método Release del proveedor.

    Si el proveedor era un proveedor puro, Release quita completamente el proveedor de la memoria activa. Sin embargo, un proveedor que no sea puro puede seguir ejecutándose después de que las llamadas de WMI Release.

Acceso al tiempo de inactividad de un proveedor

La cantidad mínima de tiempo que un proveedor permanece activo viene determinada por la propiedad ClearAfter . Puede encontrar ClearAfter en instancias de clases derivadas de la clase del sistema WMI __CacheControl en el espacio de nombres \root.

En la lista siguiente se describen las clases derivadas de __CacheControl, que controla la descarga del proveedor:

Puede cambiar la cantidad mínima de tiempo que WMI permite que un proveedor permanezca inactivo editando la propiedad ClearAfter en la instancia de control de caché para un tipo específico de proveedor. Por ejemplo, para limitar la cantidad de tiempo que un proveedor de propiedades puede permanecer inactivo, editaría la propiedad ClearAfter de una instancia de __PropertyProviderCacheControl en el espacio de nombres de \r oot.

Descarga de un proveedor que también es un cliente WMI

Es posible que el proveedor tenga que permanecer como cliente de WMI una vez que haya completado las funciones del proveedor a las que se llamó para realizar. Por ejemplo, un proveedor de notificaciones push puede necesitar emitir consultas a WMI. Para obtener más información, vea Determinar si el estado es de inserción o extracción. En este caso, la propiedad Pure de la instancia de __Win32Provider que representa el proveedor debe establecerse en TRUE. Si la propiedad Pure está establecida en FALSE, el proveedor se prepara para descargar llamando a IUnknown::Release en todos los puntos de interfaz pendientes cuando WMI llama al método Release de su interfaz principal. Para obtener más información, vea la sección Comentarios de __Win32Provider.

En el procedimiento siguiente se describe cómo implementar un método de versión para la interfaz principal del proveedor.

Para eliminar un proveedor

  1. Libere todos los punteros de interfaz retenidos por WMI cuando WMI llama al método Release de la interfaz principal de su proveedor.

    Normalmente, un proveedor contiene punteros a las interfaces IWbemServices e IWbemContext proporcionadas en IWbemProviderInit::Initialize.

  2. Si la propiedad Pure de la instancia __Win32Provider asociada está establecida en FALSE, el proveedor puede pasar al rol de aplicación cliente después de que WMI llame a Release. Sin embargo, WMI no puede descargar un proveedor que funciona como sistema cliente, lo que aumenta la sobrecarga del sistema.

    Un proveedor con Pure establecido en TRUE existe únicamente para atender solicitudes. Por lo tanto, este tipo de proveedor no puede asumir el rol de una aplicación cliente y WMI puede desactivarlo.

Desactivar un proveedor durante el apagado

En circunstancias normales, usar las pautas en Descarga de un proveedor que también es un cliente WMI permite que WMI descargue su proveedor correctamente. Sin embargo, puede encontrarse con situaciones en las que WMI no puede instigar los procedimientos de descarga normales, como cuando el usuario decide apagar el sistema. Mediante el uso de un modelo transaccional para el almacenamiento de datos, además de implementar una buena estrategia de limpieza, puede asegurarse de que su proveedor se desactiva correctamente.

El usuario puede detener WMI en cualquier momento. En tal situación, WMI no descarga ningún proveedor ni llama al punto de entrada DllCanUnloadNow en ningún proveedor en proceso. Además, si un proveedor en proceso está en medio de una llamada de método en el momento del apagado, WMI podría terminar el subproceso en ejecución en medio de la llamada. En esta circunstancia, WMI no llama a rutinas que normalmente controlan la limpieza, como un destructor de objetos. Como máximo, WMI llamará solo a DllMain .

Cuando el sistema operativo apaga WMI, el sistema libera automáticamente toda la memoria asignada a un proveedor en proceso. El sistema operativo también cierra la mayoría de los recursos que mantiene el proveedor, como identificadores de archivo, identificadores de ventana, etc. El proveedor no necesita realizar ninguna acción específica para que esto suceda.

Dado que WMI puede apagarse en medio de una llamada, un proveedor no debe dejar orígenes de datos en un estado incoherente. Dejar tus datos en un estado incoherente no es un problema para proveedores de solo lectura. Sin embargo, los proveedores con funcionalidades de escritura pueden querer implementar algún tipo de modelo de transacción para permitir una reversión segura después de una terminación abrupta.

Aunque el sistema operativo puede liberar algunos recursos generales del sistema, el sistema no libera automáticamente todos los recursos. Por ejemplo, es posible que el sistema operativo no libere un socket o una conexión de base de datos. En su lugar, es posible que el proveedor tenga que limpiar manualmente estos recursos. Para evitar estos problemas, puede implementar su proveedor externamente al proceso o agregar código de depuración.

La solución más sencilla es implementar el proveedor fuera del proceso. Un proveedor fuera de proceso no se elimina cuando WMI se cierra, aunque WMI liberará el proveedor después de un tiempo de espera COM. Los proveedores para los que los problemas de solidez de limpieza y finalización son más importantes que el rendimiento puede estar fuera del proceso.

Si debe colocar código de limpieza en su proveedor de servicios, tiene dos opciones. Un lugar para realizar este tipo de limpieza es DllMain, la función de punto de entrada de DLL que el sistema operativo llama cuando se descarga la DLL. El código de limpieza se puede agregar directamente a DllMain, ejecutándolo en respuesta a DLL_PROCESS_DETACH. La implementación de código de limpieza en DllMain puede ser algo difícil de organizar, especialmente en entornos de programación como MFC o ATL. Para obtener más información, consulte el artículo de Microsoft Knowledge Base Q148791, "How to Provide Your Own DllMain in an MFC Regular DLL". (Es posible que este recurso no esté disponible en algunos idiomas y países o regiones).

Como alternativa, también podría colocar el código de limpieza en el destructor de una clase global. Para obtener más información, consulte Desactivar un proveedor. El sistema operativo Windows no asigna objetos globales en el heap. En su lugar, el sistema operativo llama a los destructores durante la descarga de DLL.

A continuación se muestra un procedimiento de limpieza simple que podría caber dentro de un objeto global para WMI.

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

Hay muchas restricciones en cuanto a lo que se puede hacer en el código de limpieza con cualquier enfoque. Por ejemplo, no se puede acceder a subprocesos ni archivos DLL que no estén vinculados implícitamente de ninguna manera. Además, no puede realizar llamadas COM en ninguna circunstancia.

Establecer descriptores de seguridad de espacio de nombres

Protección del proveedor

Desarrollar un proveedor WMI