Descargar un proveedor

Una vez que se WMI finaliza con un proveedor, se descarga el proveedor de la memoria. El principal motivo para que WMI descargue un proveedor es conservar los recursos del sistema. Por lo tanto, debe agregar código que permita a WMI descargar el proveedor de forma eficaz. La descarga de un proveedor por parte de VMI puede tardar desde el intervalo especificado en el control de caché hasta el doble de ese intervalo.

WMI descarga un proveedor de una de las siguientes maneras:

  • Se descarga el proveedor una vez que ha finalizado las tareas que tiene asignadas.
  • Se descargan rápidamente todos los proveedores cuando el usuario cierre el sistema. Tenga en cuenta que WMI descarga proveedores en proceso cuando el servicio WMI se apaga desde la línea de comandos.

Aunque el primer escenario es más común, debe escribir el proveedor para abarcar 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 descargarlo. Para obtener más información, consulte Acceder al tiempo de inactividad de un proveedor.

  • Llama al método Release del proveedor.

    Si el proveedor era un proveedor puro, Release lo quitará completamente de la memoria activa. Sin embargo, un proveedor que no sea puro puede seguir ejecutándose después de que WMI llame al método Release.

Acceder 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 que se derivan de __CacheControl, que controla la descarga del proveedor:

Para cambiar la cantidad mínima de tiempo que WMI permite a un proveedor permanecer inactivo, modifique 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, se modifica la propiedad ClearAfter de una instancia de __PropertyProviderCacheControl en el espacio de nombres \root.

Descargar un proveedor que también es un cliente WMI

Es posible que el proveedor deba seguir como cliente de WMI una vez que haya completado las funciones de proveedor solicitadas. Por ejemplo, es posible que un proveedor de inserción tenga que emitir consultas a WMI. Para obtener más información, consulte Determinar el estado de inserción o extracción. En este caso, la propiedad Pure de la instancia __Win32Provider que representa el proveedor debe establecerse en TRUE. Si la propiedad Pure se establece en FALSE, el proveedor se prepara para la descarga mediante una llamada 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, consulte la sección de comentarios de __Win32Provider.

El procedimiento siguiente describe cómo implementar un método Release para la interfaz principal del proveedor.

Para descargar un proveedor

  1. Libere todos los punteros de interfaz mantenidos en WMI cuando WMI llama al método Release de la interfaz principal del 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 se establece en FALSE, el proveedor puede transicionar al rol de la aplicación cliente después de llamar al método Release de WMI. Sin embargo, WMI no puede descargar un proveedor que funciona como sistema cliente, lo que aumenta la sobrecarga del sistema.

    Un proveedor con la propiedad Pure establecida en TRUE solo existe para las solicitudes de servicio. Por lo tanto, este tipo de proveedor no puede asumir el rol de una aplicación cliente, y WMI puede descargarlo.

Descargar un proveedor durante el apagado

En circunstancias normales, el uso de las directrices de Descarga de un proveedor que también es un cliente WMI permite a WMI descargar correctamente el proveedor. Sin embargo, puede encontrarse en 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 de transacción de almacenamiento de datos, además de implementar una buena estrategia de limpieza, puede asegurarse de que el proveedor se descargue correctamente.

El usuario puede detener WMI en cualquier momento. En esta 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 mitad de una llamada de método en el momento de apagado, WMI puede terminar el subproceso en ejecución en mitad de la llamada. En esta situación, WMI no llama a rutinas que normalmente controlan la limpieza, como un destructor de objetos. Como mucho, 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 contiene 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 mitad de una llamada, un proveedor no debe dejar orígenes de datos en estado incoherente. Dejar los datos en estado incoherente no es un problema para los proveedores de solo lectura. Sin embargo, es posible que los proveedores con funcionalidad de escritura deseen implementar algún tipo de modelo de transacción para permitir una reversión segura después de una finalizació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 el proveedor fuera de proceso o agregar código de limpieza.

La solución más sencilla es implementar el proveedor fuera de 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 limpieza y solidez de finalización son más importantes que el rendimiento puede estar fuera de proceso.

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

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

A continuación se muestra un procedimiento de limpieza sencillo que podría tener cabida en 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 de ninguna manera a los subprocesos ni los archivos DLL que no estén vinculados implícitamente. Además, no es posible hacer llamadas COM en ningún caso.

Establecer descriptores de seguridad del espacio de nombres

Protección del proveedor

Desarrollo de un proveedor WMI