Scaricamento di un provider

Al termine di WMI con un provider, il provider scarica il provider dalla memoria. Il motivo principale per cui WMI scarica un provider consiste nel conservare le risorse di sistema. È quindi necessario aggiungere codice che consenta a WMI di scaricare il provider in modo efficiente. L'intervallo specificato nel controllo cache richiede il doppio di tale intervallo per scaricare un provider da WMI.

WMI scarica un provider in uno dei modi seguenti:

  • Scaricare un provider al termine delle attività fornite dal provider.
  • Scarica rapidamente tutti i provider quando l'utente arresta il sistema. Si noti che WMI scarica i provider in-process quando il servizio WMI viene arrestato dalla riga di comando.

Anche se il primo scenario è più comune, è necessario scrivere il provider per entrambe le possibilità.

In questo argomento vengono illustrate le sezioni seguenti:

Scaricamento di un provider inattiva

WMI esegue le azioni seguenti quando scarica un provider inattiva:

  • Determina se il provider è inattiva.

    WMI utilizza la proprietà ClearAfter per determinare per quanto tempo un provider può rimanere inattiva prima di scaricare tale provider. Per altre informazioni, vedere Accesso al tempo di inattività per un provider.

  • Chiama il metodo Release del provider.

    Se il provider è un provider puro, Release rimuove completamente il provider dalla memoria attiva. Tuttavia, un provider non esaurito può continuare a essere eseguito dopo le chiamate WMI Release.

Accesso al tempo di inattività per un provider

La quantità minima di tempo per cui un provider rimane attivo è determinata dalla proprietà ClearAfter . È possibile trovare ClearAfter in istanze di classi derivate dalla classe di sistema WMI __CacheControl nello spazio dei nomi \root.

L'elenco seguente descrive le classi derivate da __CacheControl, che controlla lo scaricamento del provider:

È possibile modificare la quantità minima di tempo che WMI consente a un provider di rimanere inattivi modificando la proprietà ClearAfter nell'istanza del controllo cache per un tipo specifico di provider. Ad esempio, per limitare la quantità di tempo per cui un provider di proprietà può rimanere inattiva, è necessario modificare la proprietà ClearAfter di un'istanza di __PropertyProviderCacheControl nello spazio dei nomi \root.

Scaricamento di un provider che è anche un client WMI

Il provider potrebbe dover rimanere un client di WMI dopo aver completato le funzioni del provider che è stato chiamato per eseguire. Ad esempio, un provider di push potrebbe dover eseguire query a WMI. Per altre informazioni, vedere Determinazione dello stato push o pull. In questo caso, la proprietà Pure dell'istanza di __Win32Provider che rappresenta il provider deve essere impostata su TRUE. Se la proprietà Pure è impostata su FALSE, il provider si prepara a scaricare chiamando IUnknown::Release su tutti i punti di interfaccia in sospeso quando WMI chiama il metodo Release dell'interfaccia primaria. Per altre informazioni, vedere la sezione Osservazioni in __Win32Provider.

La procedura seguente descrive come implementare un metodo di rilascio per l'interfaccia primaria del provider.

Per scaricare un provider

  1. Rilasciare tutti i puntatori di interfaccia mantenuti su WMI quando WMI chiama il metodo Release dell'interfaccia primaria del provider.

    In genere, un provider contiene puntatori alle interfacce IWbemServices e IWbemContext fornite in IWbemProviderInit::Initialize.

  2. Se la proprietà Pure nell'istanza di __Win32Provider associata è impostata su FALSE, il provider può passare al ruolo dell'applicazione client dopo che WMI chiama Release. TUTTAVIA, WMI non può scaricare un provider che opera come sistema client, aumentando il sovraccarico del sistema.

    Un provider con Pure impostato su TRUE esiste solo per le richieste di servizio. Pertanto, questo tipo di provider non può assumere il ruolo di un'applicazione client e WMI può scaricarlo.

Scaricamento di un provider durante l'arresto

In circostanze normali, l'uso delle linee guida in Scaricamento di un provider che è anche un client WMI consente a WMI di scaricare correttamente il provider. Tuttavia, è possibile che si verifichino situazioni in cui WMI non è in grado di attivare le normali procedure di scaricamento, ad esempio quando l'utente sceglie di arrestare il sistema. Usando un modello di transazione di archiviazione dati, oltre a implementare una buona strategia di pulizia, è possibile assicurarsi che il provider venga scaricato correttamente.

L'utente può arrestare WMI in qualsiasi momento. In una situazione di questo tipo, WMI non scarica alcun provider o chiama il punto di ingresso DllCanUnloadNow in qualsiasi provider in-process. Inoltre, se un provider in-process si trova al centro di una chiamata al metodo al momento dell'arresto, WMI può eventualmente terminare il thread in esecuzione al centro della chiamata. In questa circostanza, WMI non chiama routine che normalmente gestiscono la pulizia, ad esempio un distruttore di oggetti. Al massimo, WMI chiamerà solo DllMain .

Quando il sistema operativo arresta WMI, il sistema rilascia automaticamente tutta la memoria allocata a un provider in-process. Il sistema operativo chiude anche la maggior parte delle risorse detenute dal provider, ad esempio handle di file, handle di finestra e così via. Il provider non deve eseguire alcuna azione specifica per eseguire questa operazione.

Poiché WMI può essere arrestato durante una chiamata, un provider non deve lasciare origini dati in uno stato incoerente. Lasciare i dati in uno stato incoerente non è un problema per i provider di sola lettura. Tuttavia, i provider con funzionalità di scrittura possono voler implementare un tipo di modello di transazione per consentire un rollback sicuro dopo una chiusura brusca.

Anche se il sistema operativo può rilasciare alcune risorse di sistema generali, il sistema non rilascia automaticamente tutte le risorse. Ad esempio, il sistema operativo potrebbe non rilasciare un socket o una connessione di database. Il provider potrebbe invece dover pulire manualmente tali risorse. Per evitare questi problemi, è possibile implementare il provider out-of-process oppure aggiungere codice di pulizia.

La soluzione più semplice consiste nell'implementare il provider out-of-process. Un provider out-of-process non viene terminato quando WMI viene arrestato, anche se WMI rilascia il provider dopo un timeout COM. I provider per i quali i problemi di pulizia e terminazione dell'affidabilità sono più importanti rispetto alle prestazioni potrebbero essere out-of-process.

Se è necessario inserire il codice di pulizia nel provider, sono disponibili due opzioni. Una posizione in cui eseguire questa operazione di pulizia è DllMain, il punto di ingresso dll chiama il sistema operativo durante lo scaricamento della DLL. Il codice di pulizia può essere aggiunto direttamente in DllMain, eseguendolo in risposta a DLL_PROCESS_DETACH. L'implementazione del codice di pulizia in DllMain può essere piuttosto difficile da organizzare, soprattutto in ambienti di programmazione come MFC o ATL. Per altre informazioni, vedere l'articolo della Microsoft Knowledge Base Q148791, "How to Provide Your Own DllMain in an MFC Regular DLL"." Questa risorsa potrebbe non essere disponibile in alcune lingue e paesi o aree geografiche.

In alternativa, è anche possibile inserire il codice di pulizia nel distruttore di una classe globale. Per altre informazioni, vedere Scaricamento di un provider. Il sistema operativo Windows non alloca oggetti globali nell'heap. Al contrario, il sistema operativo chiama i distruttori durante lo scaricamento della DLL.

Di seguito è riportata una semplice procedura di pulizia che può essere inclusa in un oggetto globale per WMI.

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

Esistono molte restrizioni relative alle operazioni che possono essere eseguite nel codice di pulizia con entrambi gli approcci. Ad esempio, non è possibile accedere ai thread né alle DLL che non sono collegate in modo implicito. Inoltre, non è possibile effettuare chiamate COM in alcuna circostanza.

Impostazione dei descrittori di sicurezza namepace

Protezione del provider

Sviluppo di un provider WMI