Dela via


Vägledning för att implementera In-Process-tillägg

Processtillägg läses in i alla processer som utlöser dem. Ett Shell-namnområdestillägg kan till exempel läsas in i valfri process som kommer åt Shell-namnområdet direkt eller indirekt. Shell-namnområdet används av många Shell-åtgärder, till exempel visning av en gemensam fildialogruta, lanseringen av ett dokument via dess associerade program eller hämtning av ikonen som används för att representera en fil. Eftersom processtillägg kan läsas in i godtyckliga processer måste man vara noga med att de inte påverkar värdprogrammet eller andra processtillägg negativt.

En särskilt anmärkningsvärd körning är common language runtime (CLR), även känd som den hanterade koden eller .NET Framework. Microsoft rekommenderar att du inte skriver hanterade processtillägg till Windows Explorer eller Windows Internet Explorer och anser inte att de är ett scenario som stöds.

I det här avsnittet beskrivs faktorer att tänka på när du avgör om någon annan körtid än CLR är lämplig för användning med in-proc-tillägg. Exempel på andra runtime-miljöer är Java, Visual Basic, JavaScript/ECMAScript, Delphi och C/C++-runtime-biblioteket. Det här avsnittet innehåller också några orsaker till att hanterad kod inte stöds i processtillägg.

Versionskonflikter

En versionskonflikt kan uppstå genom en runtime-miljö som inte stöder laddning av flera runtime-versioner i en enda process. Versioner av CLR före version 4.0 tillhör den här kategorin. Om inläsningen av en version av en körning förhindrar inläsning av andra versioner av samma körning kan detta skapa en konflikt om värdprogrammet eller ett annat processtillägg använder en motstridig version. Vid en konflikt mellan versioner med ett annat tillägg som är aktivt kan det vara svårt att återskapa konflikten eftersom felet kräver att rätt versioner av tillägg är i konflikt, och typen av fel beror på ordningen i vilken de stridande tilläggen laddas in.

Överväg ett pågående tillägg som skrivits med en version av CLR före version 4.0. Varje program på datorn som använder filer Öppna dialogruta kan potentiellt få dialogrutans hanterade kod och dess tillhörande CLR-beroende inläst i programmets process. Programmet eller tillägget som först läser in en pre-4.0-version av CLR i programmets process begränsar vilka versioner av CLR som kan användas senare av den processen. Om ett hanterat program med en dialogrutan Öppna bygger på en motstridig version av CLR kan tillägget misslyckas med att köras korrekt och kan orsaka fel i programmet. Om tillägget däremot är det första som läses in i en process och en motstridig version av hanterad kod försöker starta efter det (kanske ett hanterat program eller ett program som körs läser in CLR på begäran), misslyckas åtgärden. För användaren verkar det som om vissa funktioner i programmet slutar fungera slumpmässigt, eller att programmet kraschar mystiskt.

Observera att versioner av CLR som är lika med eller senare än version 4.0 vanligtvis inte är mottagliga för versionsproblemet eftersom de är utformade för att samexistera med varandra och med de flesta pre-4.0-versioner av CLR (med undantag för version 1.0, som inte kan samexistera med andra versioner). Andra problem än versionskonflikter kan dock uppstå enligt beskrivningen i resten av det här avsnittet.

Prestandaproblem

Prestandaproblem kan uppstå med körtider som medför ett betydande prestandastraff när de laddas in i en process. Prestandastraffet kan vara i form av minnesanvändning, CPU-användning, förfluten tid eller till och med adressutrymmesförbrukning. CLR, JavaScript/ECMAScript och Java är kända för att vara högpåverkande körmiljöer. Eftersom processtillägg kan läsas in i många processer och ofta görs i prestandakänsliga ögonblick (till exempel när du förbereder en meny som ska visas för användaren), kan körning med hög effekt påverka den övergripande svarstiden negativt.

Ett runtime med hög påverkan som förbrukar betydande resurser kan orsaka ett fel i värdprocessen eller ett tillägg i processen. Till exempel kan en högpåverkande körtidsmiljö som förbrukar hundratals megabyte av adressutrymmet för sin heap leda till att värdprogrammet inte kan ladda en stor datamängd. Eftersom processtillägg kan läsas in i flera processer kan dessutom hög resursförbrukning i ett enda tillägg snabbt multipliceras till hög resursförbrukning i hela systemet.

Om en körmiljö fortsätter att vara inläst eller förbruka resurser även när tillägget som använder den körmiljön har avaktiverats, är den körmiljön inte lämplig för användning i ett tillägg.

Problem som är specifika för .NET Framework

I följande avsnitt beskrivs exempel på problem med att använda hanterad kod för tillägg. De är inte en fullständig lista över alla möjliga problem som du kan stöta på. De problem som diskuteras här är både skäl till att hanterad kod inte stöds i tillägg och faktorer att överväga när du utvärderar användningen av andra exekveringsmiljöer.

Återinträde

När CLR blockerar en STA-tråd (single-threaded apartment), till exempel på grund av en Monitor.Enter, WaitHandle.WaitOne, eller en kontenderad låsningsinstruktion , går CLR, i sin standardkonfiguration, in i en kapslad meddelandeloop medan den väntar. Många tilläggsmetoder är förbjudna att bearbeta meddelanden, och denna oförutsägbara och oväntade återaktivering kan leda till avvikande beteende som är svårt att återskapa och diagnostisera.

Den flertrådade lägenheten

CLR skapar Runtime Callable Wrappers för COM-objekt (Component Object Model). Samma Runtime Callable Wrappers förstörs senare av CLR:s finalizer, som är en del av den flertrådade lägenheten (MTA). Att flytta proxyn från STA till MTA kräver marshaling, men alla gränssnitt som används av tillägg kan inte marshallas.

Livslängd för icke-deterministiska objekt

CLR har svagare livslängdsgarantier för objekt än intern kod. Många tillägg har referensantalskrav för objekt och gränssnitt, och den skräpinsamlingsmodell som används av CLR kan inte uppfylla dessa krav.

  • Om ett CLR-objekt hämtar en referens till ett COM-objekt släpps inte COM-objektreferensen som innehas av Runtime Callable Wrapper förrän Runtime Callable Wrapper har skräpinsamlats. Nondeterministiskt versionsbeteende kan vara i konflikt med vissa gränssnittskontrakt. Metoden IPersistPropertyBag::Load kräver till exempel att ingen referens till egenskapsväskan behålls av objektet när metoden Load returnerar.
  • Om en CLR-objektreferens returneras till inhemsk kod, avstår Runtime Callable Wrapper från sin referens till CLR-objektet när dess sista anrop till Release görs. Det underliggande CLR-objektet slutförs dock inte förrän det samlas in av skräpsamlaren. Nondeterministisk slutförande kan vara i konflikt med vissa gränssnittskontrakt. Till exempel måste miniatyrhanterare omedelbart frigöra alla resurser när deras referensantal sjunker till noll.

Godtagbar användning av hanterad kod och andra körningsmiljöer

Det är acceptabelt att använda hanterad kod och andra körmiljöer för att implementera tillägg utanför process. Exempel på out-of-process Shell-tillägg är följande:

  • Förhandsgranskningshanterare
  • Kommandoradsbaserade åtgärder såsom de som registrerats under undernycklarna shell\verb\kommando.
  • COM-objekt som implementeras på en lokal server för Shell-tilläggspunkter som tillåter aktivering utan process.

Vissa tillägg kan implementeras antingen som in-process- eller out-of-process-tillägg. Du kan implementera dessa tillägg som out-of-process-tillägg om de inte uppfyller dessa krav för processtillägg. I följande lista visas exempel på tillägg som kan implementeras som antingen in-process- eller out-of-process-tillägg:

  • IExecuteCommand associerad med en DelegateExecute- post som registrerats under ett shell\verb\kommando undernyckel.
  • IDropTarget associerad med CLSID som registrerats under ett -gränssnitt\verb\DropTarget undernyckel.
  • IExplorerCommandState associeras med en CommandStateHandler post som är registrerad under ett shell\verb undernyckel.