Pokyny k implementaci rozšíření In-Process
Rozšíření v procesu se načtou do všech procesů, které je aktivují. Rozšíření Shell namespace je například možné načíst do jakéhokoli procesu, který přistupuje k Shell namespace buď přímo, nebo nepřímo. Obor názvů prostředí se používá v mnoha operacích prostředí, jako je zobrazení běžného dialogového okna souboru, spuštění dokumentu prostřednictvím přidružené aplikace nebo získání ikony použité k reprezentaci souboru. Vzhledem k tomu, že rozšíření v procesu je možné načíst do libovolných procesů, je třeba věnovat pozornost tomu, že nemají negativní vliv na hostitelskou aplikaci nebo jiná rozšíření v procesu.
Jedním z obzvlášť významných runtime je CLR (Common Language Runtime), známý také jako spravovaný kód nebo rozhraní .NET Framework. Společnost Microsoft doporučuje nepsat spravovaná rozšíření pro Průzkumníka Windows nebo Internet Explorer a nepovažuje je za podporovaný scénář.
Toto téma popisuje faktory, které je potřeba vzít v úvahu, když zjistíte, jestli je jakýkoli jiný modul runtime než CLR vhodný pro použití rozšířeními v procesu. Mezi příklady dalších runtime patří Java, Visual Basic, JavaScript/ECMAScript, Delphi a knihovna runtime C/C++. Toto téma také obsahuje některé důvody, proč spravovaný kód není v rozšířeních v procesu podporován.
Konflikty verzí
Konflikt verzí může nastat prostřednictvím modulu runtime, který nepodporuje načítání více verzí modulu runtime v rámci jednoho procesu. Verze CLR před verzí 4.0 spadají do této kategorie. Pokud načítání jedné verze modulu runtime brání načtení jiných verzí stejného modulu runtime, může dojít ke konfliktu, pokud hostitelská aplikace nebo jiné rozšíření v procesu používá konfliktní verzi. V případě konfliktu verze s jiným rozšířením v procesu může být konflikt obtížné reprodukovat, protože selhání vyžaduje správné konfliktní rozšíření a režim selhání závisí na pořadí, ve kterém jsou načítána konfliktní rozšíření.
Zvažte rozšíření v procesu napsané pomocí verze CLR před verzí 4.0. Každá aplikace v počítači, která používá dialogové okno Otevřít, může potenciálně mít načtený spravovaný kód dialogového okna a související závislost CLR do procesu aplikace. Aplikace nebo rozšíření, které jako první načte verzi CLR starší než 4.0 do procesu aplikace, omezuje, které verze CLR mohou být tímto procesem následně použity. Pokud je spravovaná aplikace s dialogovým oknem Otevřít postavená na konfliktní verzi modulu CLR, rozšíření se může nesprávně spustit a způsobit selhání aplikace. Naopak, pokud je rozšíření prvním načteným v procesu a konfliktní verze spravovaného kódu se pokusí spustit poté (třeba spravovaná aplikace nebo spuštěná aplikace načte CLR na vyžádání), proces selže. Uživateli se zdá, že některé funkce aplikace náhodně přestanou fungovat nebo se aplikace záhadně chybově ukončí.
Mějte na paměti, že verze CLR rovna nebo novější než verze 4.0 nejsou obecně náchylné k problému správy verzí, protože jsou navrženy tak, aby spoluexistily s většinou verzí CLR před 4.0 (s výjimkou verze 1.0, která nemůže existovat společně s jinými verzemi). Jiné problémy, než jsou konflikty verzí, ale mohou nastat, jak je popsáno ve zbývající části tohoto tématu.
Problémy s výkonem
Problémy s výkonem můžou nastat s moduly runtime, které při načítání do procesu představují významné snížení výkonu. Výkonový postih může být ve formě využití paměti, využití procesoru, uplynulého času nebo dokonce využití adresního prostoru. Moduly CLR, JavaScript/ECMAScript a Java jsou známé jako moduly runtime s vysokým dopadem. Vzhledem k tomu, že rozšíření za běhu je možné načíst do mnoha procesů a často se tak děje v okamžicích citlivých na výkon (například při přípravě nabídky, která se má zobrazit uživateli), mohou runtimy s vysokým dopadem negativně ovlivnit celkovou odezvu.
Běhové prostředí s vysokým dopadem, které spotřebovává významné prostředky, může způsobit selhání v hostitelském procesu nebo jiném rozšíření v rámci procesu. Například modul runtime s vysokým dopadem, který využívá stovky megabajtů adresního prostoru pro haldu, může způsobit, že hostitelská aplikace nemůže načíst velkou datovou sadu. Vzhledem k tomu, že rozšíření v procesu je možné načíst do několika procesů, může se vysoká spotřeba prostředků v jednom rozšíření rychle vynásobit na vysokou spotřebu prostředků v celém systému.
Pokud modul runtime zůstane načtený nebo jinak bude dál využívat prostředky i v případě, že rozšíření, které používá daný modul runtime, se nenačte, pak tento modul runtime není vhodný pro použití v rozšíření.
Problémy související s rozhraním .NET Framework
V následujících částech najdete příklady problémů zjištěných při použití spravovaného kódu pro rozšíření. Nejedná se o úplný seznam všech možných problémů, se kterými se můžete setkat. Zde diskutovaná témata jsou důvody, proč spravovaný kód není podporován v rozšířeních, a body, které je třeba zvážit při hodnocení použití jiných runtime.
Opětovná vstupnost
Když CLR blokuje jednovláknové (STA) vlákno, například kvůli Monitor.Enter, WaitHandle.WaitOne nebo obsazenému lock příkazu, CLR ve své standardní konfiguraci, se zadá do vnořené smyčky zpráv během čekání. Mnoho rozšiřovacích metod je zakázáno zpracovávat zprávy a tento nepředvídatelný a neočekávaný opětovný vstup může vést k neobvyklému chování, které je obtížné reprodukovat a diagnostikovat.
Apartmán s více vlákny
CLR vytvoří běhové volací obálky pro objekty Component Object Model (COM). Tyto stejné obálky volatelné moduly runtime jsou později zničeny finalizátorem CLR, který je součástí vícevláknového apartmánu (MTA). Přesunutí proxy z STA na MTA vyžaduje sériové zpracování, ale ne všechna rozhraní používaná rozšířeními lze zpracovat.
Ne deterministické životnosti objektů
CLR má slabší záruky životnosti objektů než nativní kód. Mnoho rozšíření má požadavky na počet odkazů na objekty a rozhraní a model uvolňování paměti používaný CLR nemůže tyto požadavky splnit.
- Pokud objekt CLR získá odkaz na objekt COM, odkaz na objekt COM uchovávaný obálkou runtime callable wrapper není uvolněn, dokud modul runtime callable Wrapper nebude uvolněn. Nedeterministické chování vydané verze může kolidovat s některými kontrakty rozhraní. Například metoda IPersistPropertyBag::Load vyžaduje, aby objekt po dokončení metody Load nezachoval žádný odkaz na kontejner vlastností.
- Pokud je referenční odkaz na objekt CLR vrácen do nativního kódu, obálka volání modulu runtime se zřekne svého odkazu na objekt CLR ve chvíli, kdy je provedeno její poslední volání Release, ale podkladový objekt CLR není finalizován, dokud není uvolněn v rámci správy paměti. Nedeterministická finalizace může kolidovat s některými smlouvami rozhraní. Například obslužné rutiny miniatur se vyžadují k okamžitému uvolnění všech prostředků, když počet odkazů klesne na nulu.
Přijatelná použití spravovaného kódu a dalších běhových prostředí.
Je přijatelné použít spravovaný kód a další moduly runtime k implementaci rozšíření mimo proces. Mezi příklady rozšíření Shell mimo proces patří:
- Obslužné rutiny náhledu
- Akce založené na příkazovém řádku, například akce zaregistrované v prostředí \příkaz\příkaz podklíčů.
- Objekty COM implementované na místním serveru pro body rozšíření prostředí Shell, které umožňují aktivaci mimo hlavní proces.
Některá rozšíření lze implementovat buď jako rozšíření v rámci procesu, nebo mimo proces. Tato rozšíření můžete implementovat jako rozšíření mimo proces, pokud nesplňují tyto požadavky pro rozšíření v procesu. Následující seznam ukazuje příklady rozšíření, která je možné implementovat jako rozšíření v procesu nebo rozšíření mimo proces:
- IExecuteCommand přidružené k DelegateExecute záznam zaregistrovaný pod shell\příkazového\slovesa podklíče.
- IDropTarget přidružené k CLSID registrovaným pod \slovesem\DropTarget podklíčem.
- IExplorerCommandState přidružené k položce CommandStateHandler zaregistrované pod shellu\podklíči příkazu.