Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Depois que o WMI tiver concluído com um provedor, ele descarregará o provedor da memória. O principal motivo pelo qual o WMI descarrega um provedor é para conservar recursos do sistema. Portanto, você deve adicionar um código que permita que o WMI descarregue seu provedor de maneira eficiente. Pode levar entre o intervalo especificado no controle de cache e o dobro desse intervalo para o WMI descarregar um provedor.
O WMI descarrega um provedor de uma das seguintes maneiras:
- Descarregue um provedor depois que ele concluir as tarefas atribuídas.
- Descarregue rapidamente todos os provedores quando o usuário desligar o sistema. Observe que o WMI descarrega provedores em processo quando o serviço WMI é desligado da linha de comando.
Embora o primeiro cenário seja mais comum, você deve entrar em contato com seu provedor para ambas as opções.
As seções a seguir são discutidas neste tópico:
- Desativando um fornecedor inativo
- Acessando o tempo ocioso de um provedor
- Descarregando um provedor que também é um cliente WMI
- Descarregando um provedor durante o desligamento
- tópicos relacionados
Descarregando um provedor ocioso
O WMI executa as seguintes ações quando descarrega um provedor ocioso:
Determina se o provedor está ocioso.
O WMI usa a propriedade ClearAfter para determinar por quanto tempo um provedor pode permanecer ocioso antes de descarregar esse provedor. Para obter mais informações, consulte Acessando o tempo ocioso de um provedor.
Chama o método Release do provedor.
Se o provedor era um provedor puro, o Release remove completamente o provedor da memória ativa. No entanto, um provedor não puro pode continuar a ser executado após o WMI chamar Release.
Acessando o tempo ocioso de um provedor
O tempo mínimo que um provedor permanece ativo é determinado pela propriedade ClearAfter . Você pode encontrar ClearAfter em instâncias de classes derivadas da classe de sistema WMI __CacheControl no namespace \root.
A lista a seguir descreve as classes derivadas de __CacheControl, que controla o descarregamento do provedor:
- __EventConsumerProviderCacheControl
- __EventProviderCacheControl
- __EventSinkCacheControl
- __ObjectProviderCacheControl
- __PropertyProviderCacheControl
Você pode alterar a quantidade mínima de tempo que o WMI permite que um provedor permaneça inativo editando a propriedade ClearAfter na instância de controle de cache para um tipo específico de provedor. Por exemplo, para limitar o tempo em que um provedor de propriedades pode permanecer ocioso, você editaria a propriedade ClearAfter de uma instância de __PropertyProviderCacheControl no namespace \root.
Descarregando um provedor que também é um cliente WMI
Seu provedor pode precisar permanecer como um cliente do WMI depois de concluir as funções de provedor que ele foi chamado para executar. Por exemplo, um provedor push pode precisar emitir consultas para o WMI. Para obter mais informações, consulte Determinando o Status de Push ou Pull. Nesse caso, a propriedade Pure da instância de __Win32Provider que representa o provedor deve ser definida como TRUE. Se a propriedade Pure estiver definida como FALSE, o provedor se preparará para descarregar chamando IUnknown::Release em todos os pontos de interface pendentes quando o WMI chamar o método Release de sua interface primária. Para obter mais informações, consulte a seção Comentários no __Win32Provider.
O procedimento a seguir descreve como implementar um método de versão para a interface primária do seu provedor.
Para desativar um provedor
Libere todos os ponteiros de interface mantidos no WMI quando o WMI chamar o método Release da interface primária do seu provedor.
Normalmente, um provedor mantém ponteiros para as interfaces IWbemServices e IWbemContext fornecidas em IWbemProviderInit::Initialize.
Se a propriedade Pure na instância de __Win32Provider associada estiver definida como FALSE, o provedor poderá fazer a transição para a função do aplicativo cliente após a WMI chamar Release. No entanto, o WMI não pode descarregar um provedor que esteja operando como um sistema cliente, o que aumenta a sobrecarga do sistema.
Um provedor com Pure definido como TRUE existe apenas para atender solicitações. Portanto, esse tipo de provedor não pode funcionar como um aplicativo cliente e o WMI pode descarregá-lo.
Descarregando um provedor durante o desligamento
Em circunstâncias normais, o uso das diretrizes no descarregamento de um provedor que também é um cliente WMI permite que o WMI descarregue seu provedor corretamente. No entanto, você pode encontrar situações em que o WMI não consegue instigar os procedimentos normais de descarregamento, como quando o usuário opta por desligar o sistema. Ao utilizar um modelo de transação para armazenamento de dados, juntamente com a implementação de uma boa estratégia de limpeza, você pode garantir que seu provedor seja desligado de forma adequada.
O usuário pode interromper o WMI a qualquer momento. Nessa situação, o WMI não descarrega nenhum provedor nem chama o ponto de entrada DllCanUnloadNow em nenhum provedor que esteja em execução. Além disso, se um provedor em processo estiver no meio de uma chamada de método no momento do desligamento, o WMI poderá encerrar o thread em execução no meio da chamada. Nesta circunstância, a WMI não chama rotinas que normalmente lidam com a limpeza, como um destruidor de objetos. No máximo, o WMI chamará apenas DllMain .
Quando o sistema operacional desliga o WMI, o sistema libera automaticamente toda a memória alocada para um provedor em processo. O sistema operacional também fecha a maioria dos recursos mantidos pelo provedor, como identificadores de arquivo, identificadores de janela e assim por diante. O provedor não precisa tomar nenhuma ação específica para fazer isso acontecer.
Como o WMI pode ser desligado no meio de uma chamada, um provedor não deve deixar fontes de dados em um estado inconsistente. Deixar seus dados em estado inconsistente não representa um problema para provedores de somente leitura. No entanto, provedores com capacidade de escrita podem querer implementar algum tipo de modelo de transação para permitir uma revogação segura após uma terminação abrupta.
Embora o sistema operacional possa liberar alguns recursos gerais do sistema, o sistema não libera automaticamente todos os recursos. Por exemplo, o sistema operacional pode não liberar um soquete ou uma conexão de banco de dados. Em vez disso, o provedor pode precisar limpar manualmente esses recursos. Para evitar esses problemas, você pode implementar seu provedor fora do processo ou adicionar código de finalização.
A solução mais simples é implementar seu provedor fora de processo. Um provedor fora de processo não é terminado quando o WMI é desligado, embora o WMI libere o provedor após um timeout de COM. Provedores para os quais os problemas de robustez na limpeza e término são mais importantes do que o desempenho podem operar fora do processo.
Se você precisar colocar o código de limpeza em seu provedor, terá duas opções. Um local para executar esse tipo de limpeza é dllMain, a função de ponto de entrada DLL que o sistema operacional chama ao descarregar a DLL. O código de limpeza pode ser adicionado diretamente ao DllMain, executando-o em resposta a DLL_PROCESS_DETACH. Implementar o código de limpeza no DllMain pode ser um pouco difícil de organizar, especialmente em ambientes de programação como MFC ou ATL. Para obter mais informações, consulte o artigo da Base de Dados de Conhecimento da Microsoft Q148791: "Como fornecer seu próprio DllMain em uma DLL regular MFC". (Esse recurso pode não estar disponível em alguns idiomas e países ou regiões.)
Como alternativa, você também pode colocar o código de limpeza no destruidor de uma classe global. Para obter mais informações, consulte Removendo um Provedor. O sistema operacional Windows não aloca objetos globais no heap. Em vez disso, o sistema operacional chama os destrutores durante o descarregamento de uma DLL.
A seguir está um procedimento de limpeza simples que pode ser inserido dentro de um objeto global para Instrumentação de Gerenciamento do Windows (WMI).
class CMyCleanup
{
~CMyCleanup()
{
CloseHandle(m_hOpenFile);
CloseDatabaseConnection(g_hDatabase);
}
} g_Cleanup;
Há muitas restrições quanto ao que pode ser feito no código de limpeza com qualquer abordagem. Por exemplo, nem threads nem DLLs que não estão implicitamente vinculados podem ser acessados de qualquer forma. Além disso, você não pode fazer chamadas COM em nenhuma circunstância.
Tópicos relacionados