Sdílet prostřednictvím


Uvolnění zprostředkovatele

Jakmile WMI dokončí práci se zprostředkovatelem, uvolní ho z paměti. Hlavním důvodem, proč WMI uvolní poskytovatele, je šetřit systémové prostředky. Proto musíte přidat kód, který službě WMI umožňuje efektivním způsobem uvolnit poskytovatele. Od intervalu zadaného v ovládacím prvku mezipaměti trvá až dvakrát tento interval, aby služba WMI odložil zprostředkovatele.

WMI uvolní zprostředkovatele jedním z následujících způsobů:

  • Jakmile poskytovatel dokončí úkoly, které mu byly dány, odstraňte poskytovatele.
  • Rychlé uvolnění všech poskytovatelů, když uživatel vypne systém. Všimněte si, že služba WMI uvolní poskytovatele v procesu, když je služba WMI vypnuta z příkazového řádku.

I když je první scénář častější, musíte napsat svému poskytovateli pro obě varianty.

V tomto tématu jsou popsány následující části:

Uvolnění neaktivního zprostředkovatele

Rozhraní WMI provede při uvolnění nečinného zprostředkovatele následující akce:

  • Určuje, jestli je poskytovatel nečinný.

    Rozhraní WMI používá vlastnost ClearAfter k určení, jak dlouho může poskytovatel zůstat nečinný před uvolněním tohoto poskytovatele. Další informace najdete v tématu Přístup k době nečinnosti zprostředkovatele.

  • Volá metodu Release poskytovatele.

    Pokud byl zprostředkovatel čistým poskytovatelem, Release ho zprostředkovatel zcela odebere z aktivní paměti. Po volání rozhraní WMI uvolněnívšak může nečistý poskytovatel nadále běžet.

Přístup k době nečinnosti poskytovatele

Minimální doba, po kterou poskytovatel zůstane aktivní, je určena vlastností ClearAfter. ClearAfter najdete v instancích tříd odvozených ze systémové třídy WMI __CacheControl v oboru názvů \root.

Následující seznam popisuje třídy odvozené z __CacheControl, které řídí uvolňování zprostředkovatele:

Minimální dobu, po kterou WMI umožňuje, aby zprostředkovatel zůstal neaktivní, můžete změnit úpravou vlastnosti ClearAfter v instanci ovládacího prvku mezipaměti pro konkrétní typ poskytovatele. Pokud například chcete omezit dobu, po kterou může poskytovatel vlastnosti zůstat nečinný, upravte vlastnost ClearAfter u instance __PropertyProviderCacheControl v oboru názvů \root.

Uvolnění zprostředkovatele, který současně slouží jako klient rozhraní WMI

Váš poskytovatel možná bude muset zůstat klientem rozhraní WMI po dokončení funkcí poskytovatele, ke kterým byl volán. Poskytovatel nabízených oznámení může například potřebovat vydávat dotazy do rozhraní WMI. Pro více informací si přečtěte Určení stavu Push nebo Pull. V tomto případě by měla být vlastnost Pure instance __Win32Provider, která představuje zprostředkovatele, nastavena na hodnotu TRUE. Pokud je vlastnost Pure nastavena na hodnotu FALSE, zprostředkovatel se připraví na uvolnění voláním IUnknown::Release na všech nevyřízených bodech rozhraní, když WMI volá metodu Release primárního rozhraní. Další informace naleznete v části Poznámky v __Win32Provider.

Následující postup popisuje, jak implementovat metodu vydání pro primární rozhraní vašeho poskytovatele.

Uvolnit poskytovatele

  1. Uvolněte všechny ukazatele rozhraní uchovávané proti rozhraní WMI, když rozhraní WMI volá metodu Release primárního rozhraní vašeho poskytovatele.

    Zprostředkovatel obvykle drží ukazatele na rozhraní IWbemServices a rozhraní IWbemContext předaná v IWbemProviderInit::Initialize.

  2. Pokud je vlastnost Pure v přidružené instanci __Win32Provider nastavena na hodnotu FALSE, může poskytovatel přejít na roli klientské aplikace po volání rozhraní WMI Release. Rozhraní WMI však nemůže uvolnit poskytovatele, který pracuje jako klientský systém, což zvyšuje režii systému.

    Zprostředkovatel s Pure nastaveným na TRUE existuje pouze pro vyřízení žádostí. Tím pádem tento typ poskytovatele nemůže převzít roli klientské aplikace a WMI jej může uvolnit.

Uvolnění poskytovatele během vypínání

Za normálních okolností pokyny v části Uvolnění zprostředkovatele, který je také klientem rozhraní WMI umožňují službě WMI správně uvolnit vašeho poskytovatele. Můžete ale narazit na situace, kdy rozhraní WMI nedokáže zahájit obvyklé postupy uvolňování, například když se uživatel rozhodne vypnout systém. Použitím transakčního modelu pro ukládání dat a implementací vhodné strategie čištění zajistíte, že bude váš poskytovatel správně odpojen.

Uživatel může rozhraní WMI kdykoli zastavit. V takové situaci rozhraní WMI nezvolá žádné zprostředkovatele ani nevolá DllCanUnloadNow vstupní bod u jakéhokoli zprostředkovatele v procesu. Navíc pokud je zprostředkovatel v procesu uprostřed volání metody v době vypnutí, může rozhraní WMI ukončit spuštěné vlákno uprostřed volání. V této situaci rozhraní WMI nevolá rutiny, které obvykle zpracovávají čištění, jako je například destruktor objektu. Nejvíce WMI bude volat pouze DllMain .

Když operační systém vypne rozhraní WMI, systém automaticky uvolní veškerou paměť přidělenou poskytovateli v procesu. Operační systém také zavře většinu prostředků uchovávaných poskytovatelem, jako jsou popisovače souborů, popisovače oken atd. Poskytovatel nemusí provést žádnou konkrétní akci, aby k tomu došlo.

Vzhledem k tomu, že služba WMI se může vypnout uprostřed volání, poskytovatel by neměl ponechat zdroje dat v nekonzistentním stavu. Ponechání dat v nekonzistentním stavu není problém pro poskytovatele pouze pro čtení. Poskytovatelé s funkcemi zápisu však mohou chtít implementovat určitý druh transakčního modelu, který umožní bezpečné vrácení zpět po náhlém ukončení.

Operační systém může uvolnit některé obecné systémové prostředky, ale systém automaticky neuvolní všechny prostředky. Operační systém například nemusí uvolnit soket nebo připojení k databázi. Místo toho může poskytovatel tyto prostředky ručně vyčistit. Abyste se těmto problémům vyhnuli, můžete buď implementovat poskytovatele mimo proces, nebo můžete přidat kód pro vyčištění.

Nejjednodušším řešením je implementovat poskytovatele mimo proces. Při vypnutí rozhraní WMI není ukončen poskytovatel mimo proces, přestože služba WMI uvolní poskytovatele po vypršení časového limitu modelu COM. Poskytovatelé, u kterých je odolnost při čištění a ukončení důležitější než výkon, mohou být mimo procesní prostředí.

Pokud musíte do svého poskytovatele umístit kód pro úklid, máte dvě možnosti. Jedním z míst k provedení tohoto druhu čištění je DllMain, funkce vstupního bodu knihovny DLL, kterou operační systém volá při uvolnění knihovny DLL. Kód čištění lze přidat přímo do DllMain, kde se spustí v reakci na DLL_PROCESS_DETACH. Implementace čisticího kódu ve funkci DllMain může být poněkud obtížná, zejména v programovacích prostředích, jako je MFC nebo ATL. Další informace naleznete v článku znalostní báze Microsoft Knowledge Base Q148791 "Jak poskytnout vlastní DllMain v pravidelné DLL MFC." (Tento prostředek nemusí být dostupný v některých jazycích a zemích nebo oblastech.)

Případně můžete kód čištění umístit také do destruktoru globální třídy. Další informace naleznete v tématu Uvolnění zprostředkovatele. Operační systém Windows nepřiděluje globální objekty v haldě. Místo toho operační systém volá destruktory během uvolnění knihovny DLL.

Následuje jednoduchý postup čištění, který by mohl být integrován do globálního objektu pro WMI.

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

Existuje mnoho omezení ohledně toho, co lze udělat v kódu úklidu s kterýmkoli z přístupů. Například ani vlákna ani žádné knihovny DLL, které nejsou implicitně propojeny, mohou být přístupné žádným způsobem. Za žádných okolností nemůžete provádět COM volání.

Nastavení bezpečnostních popisovačů oboru názvů

Zabezpečení vašeho poskytovatele

vývoj zprostředkovatele WMI