Dela via


Paketera och distribuera resurser i .NET-appar

Program förlitar sig på .NET Framework Resource Manager, som representeras av ResourceManager klassen, för att hämta lokaliserade resurser. Resource Manager förutsätter att en nav- och ekermodell används för att paketera och distribuera resurser. Hubben är huvudsammansättningen som innehåller den icke-lokaliserade körbara koden och resurserna för en enda kultur, som kallas neutral eller standardkultur. Standardkulturen är återställningskulturen för programmet. det är den kultur vars resurser används om lokaliserade resurser inte kan hittas. Varje eker ansluter till en satellitsammansättning som innehåller resurser för en enda kultur, men som inte innehåller någon kod.

Det finns flera fördelar med den här modellen:

  • Du kan stegvis lägga till resurser för nya kulturer när du har distribuerat ett program. Eftersom efterföljande utveckling av kulturspecifika resurser kan kräva en betydande tid kan du släppa huvudprogrammet först och leverera kulturspecifika resurser vid ett senare tillfälle.
  • Du kan uppdatera och ändra ett programs satellitsammansättningar utan att kompilera om programmet.
  • Ett program behöver bara läsa in de satellitsammansättningar som innehåller de resurser som behövs för en viss kultur. Detta kan avsevärt minska användningen av systemresurser.

Det finns dock även nackdelar med den här modellen:

  • Du måste hantera flera uppsättningar resurser.
  • Den initiala kostnaden för att testa ett program ökar eftersom du måste testa flera konfigurationer. Observera att det på lång sikt blir enklare och billigare att testa ett kärnprogram med flera satelliter än att testa och underhålla flera parallella internationella versioner.

Namngivningskonventioner för resurser

När du paketerar applikationens resurser måste du namnge dem med hjälp av de namngivningskonventioner för resurser som den gemensamma språkets körning förväntar sig. Körmiljön identifierar en resurs genom dess kulturnamn. Varje kultur får ett unikt namn, vilket vanligtvis är en kombination av ett kulturnamn med två bokstäver som är associerat med ett språk och, om det behövs, ett subkulturnamn med två bokstäver som är associerat med ett land eller en region. Subkulturnamnet följer kulturnamnet, avgränsat med ett bindestreck (-). Exempel är ja-JP för japanska som talas i Japan, en-US för engelska som talas i USA, de-DE tyska som talas i Tyskland eller de-AT för tyska som talas i Österrike. Se kolumnen Språktagg i listan över språk-/regionnamn som stöds av Windows. Kulturnamn följer standarden som definieras av BCP 47.

Anmärkning

Det finns vissa undantag för kulturnamn med två bokstäver, till exempel zh-Hans för kinesiska (förenklad).

Mer information finns i Skapa resursfiler och Skapa satellitsammansättningar.

Återställningsprocessen för resursen

Hubb- och ekermodellen för paketering och distribution av resurser använder en återfallsprocess för att hitta lämpliga resurser. Om ett program begär en lokaliserad resurs som inte är tillgänglig söker den vanliga språkkörningen i kulturhierarkin efter en lämplig återställningsresurs som bäst matchar användarens programbegäran och genererar endast ett undantag som en sista utväg. Om en lämplig resurs hittas på varje nivå i hierarkin använder körningen den. Om resursen inte hittas fortsätter sökningen på nästa nivå.

För att förbättra uppslagsprestandan, använd NeutralResourcesLanguageAttribute attributet för din huvudsammansättning och ange namnet på det neutrala språk som kommer att fungera med din huvudsammansättning.

Återställningsprocess för .NET Framework-resurser

Återställningsprocessen för .NET Framework-resurser omfattar följande steg:

Tips/Råd

Du kanske kan använda konfigurationselementet< relativeBindForResources> för att optimera återfallsprocessen för resurser och processen med vilken körningen sonderar efter resurssammansättningar. Mer information finns i Optimera återställningsprocessen för resurser.

  1. Körtiden kontrollerar först den globala samlingscachen för en samling som matchar programmets begärda kultur.

    Den globala sammansättningscacheminnet kan lagra resurssammansättningar som delas av många program. Detta gör att du inte behöver inkludera specifika uppsättningar resurser i katalogstrukturen för varje program som du skapar. Om runtime hittar en referens till assemblyn söker den efter den begärda resursen i assemblyn. Om den hittar posten i samlingen använder den begärda resursen. Om posten inte hittas fortsätter sökningen.

  2. Körtiden kontrollerar sedan katalogen för den nuvarande körande programmet efter en underkatalog som matchar den begärda kulturen. Om den hittar underkatalogen söker den i underkatalogen efter en giltig satellitsammansättning för den begärda kulturen. Körtiden söker sedan i satellitsammansättningen efter den begärda resursen. Om den hittar resursen i sammansättningen använder den den. Om den inte hittar resursen fortsätter sökningen.

  3. Programkörningen kontrollerar sedan Windows Installer för att bestämma om satellit-assemblyn ska installeras på begäran. I så fall hanterar den installationen, läser in sammansättningen och söker efter den eller den begärda resursen. Om den hittar resursen i sammansättningen använder den den. Om den inte hittar resursen fortsätter sökningen.

  4. Körningen genererar AppDomain.AssemblyResolve händelsen för att indikera att den inte kan hitta satellitsammansättningen. Om du väljer att hantera händelsen kan händelsehanteraren returnera en referens till satellitsammansättningen vars resurser ska användas för sökningen. Annars returnerar händelsehanteraren null och sökningen fortsätter.

  5. Körtiden söker sedan igenom den globala assembly-cacheminnet igen, denna gång efter föräldrasammansättningen av den begärda kulturinställningen. Om den överordnade sammansättningen finns i den globala sammansättningscachen letar runtime-miljön efter den begärda resursen i sammansättningen.

    Den överordnade kulturen definieras som lämplig reservkultur. Överväg föräldrar som reservkandidater, eftersom det är bättre att tillhandahålla en resurs än att kasta ett undantag. Med den här processen kan du också återanvända resurser. Du bör endast ta med en viss resurs på den överordnade nivån om den underordnade kulturen inte behöver lokalisera den begärda resursen. Om du till exempel tillhandahåller satellitsammansättningar för en (neutral engelska), en-GB (engelska som talas i Storbritannien) och en-US (engelska som talas i USA), skulle satelliten en innehålla den gemensamma terminologin, och en-GB satelliterna och en-US kan ge åsidosättningar endast för de termer som skiljer sig åt.

  6. Körningen kontrollerar sedan katalogen för den pågående sammansättningen för att se om den innehåller en överordnad katalog. Om det finns en överordnad katalog söker körtidsmiljön i katalogen efter en giltig satellitsammansättning för den överordnade kulturen. Om den hittar sammansättningen, söker körtiden den begärda resursen i sammansättningen. Om den hittar resursen använder den den. Om den inte hittar resursen fortsätter sökningen.

  7. Körmiljön frågar Windows Installer sedan för att avgöra om föräldra-satellitsammansättningen ska installeras på begäran. I så fall hanterar den installationen, läser in sammansättningen och söker efter den eller den begärda resursen. Om den hittar resursen i sammansättningen använder den den. Om den inte hittar resursen fortsätter sökningen.

  8. Körningsmiljön genererar AppDomain.AssemblyResolve händelsen för att indikera att den inte kan hitta en lämplig fallback-resurs. Om du väljer att hantera händelsen kan händelsehanteraren returnera en referens till satellitsammansättningen vars resurser ska användas för sökningen. Annars returnerar händelsehanteraren null och sökningen fortsätter.

  9. Under körningen söker systemet sedan efter överordnade assemblys, precis som i de föregående tre stegen, genom många potentiella nivåer. Varje kultur har bara en överordnad, som definieras av CultureInfo.Parent egenskapen, men en överordnad kan ha sin egen överordnad. Sökningen efter överordnade kulturer stoppas när en kulturs Parent egenskap returnerar CultureInfo.InvariantCulture. För resursåterställning betraktas den invarianta kulturen inte som en överordnad kultur eller en kultur som kan ha resurser.

  10. Om den kultur som ursprungligen angavs och alla föräldrar har genomsökts och resursen fortfarande inte hittas används resursen för standardkulturen (återställning). Vanligtvis ingår resurserna för standardkulturen i huvudprogramsammansättningen. Du kan dock ange värdet Satellite för attributet Location för egenskapen NeutralResourcesLanguageAttribute att indikera att den slutliga reservlösningen för resurser är en satellitsamling i stället för huvudsamlingen.

    Anmärkning

    Standardresursen är den enda resurs som kan kompileras med huvudsammansättningen. Om du inte anger en satellitassembly med hjälp av NeutralResourcesLanguageAttribute-attributet är det den sista utvägen (slutliga alternativ). Därför rekommenderar vi att du alltid inkluderar en standarduppsättning med resurser i huvudsammansättningen. Detta förhindrar att undantag utlöses. Genom att inkludera en standardresurs anger du en reserv för alla resurser och ser till att minst en resurs alltid finns för användaren, även om den inte är kulturellt specifik.

  11. Om körningen slutligen inte hittar någon resurs för en standardkultur (reservkultur) genereras ett MissingManifestResourceException- eller MissingSatelliteAssemblyException-undantag för att indikera att resursen inte kunde hittas.

Anta till exempel att programmet begär en resurs lokaliserad för spanska (Mexiko) ( es-MX kulturen). Körningstiden söker först i den globala sammansättningscachen efter den sammansättning som matchar es-MX, men hittar den inte. Körningen söker sedan i katalogen för den för närvarande körande assembly efter en es-MX-katalog. Om det misslyckas söker körningen återigen i den globala sammansättningscachen efter en överordnad sammansättning som återspeglar lämplig reservkultur – i det här fallet es (spanska). Om den överordnade sammansättningen inte hittas, söker körsystemet igenom alla potentiella nivåer av överordnade sammansättningar för es-MX-kulturen tills det hittar en motsvarande resurs. Om en resurs inte hittas använder körningstiden resursen för standardkulturen.

Optimera återfallsprocessen för resurser i .NET Framework

Under följande villkor kan du optimera den process genom vilken körtiden söker efter resurser i satellitförsamlingar.

  • Satellitsammansättningar distribueras på samma plats som kodsammansättningen. Om kodsammansättningen installeras i Global Assembly Cache, installeras även satellitsammansättningar i den globala sammansättningscachen. Om kodsammansättningen installeras i en katalog installeras satellitsammansättningar i kulturspecifika mappar i katalogen.

  • Satellitsammansättningar installeras inte på begäran.

  • Programkoden hanterar inte händelsen AppDomain.AssemblyResolve .

Du optimerar avsökningen för satellitsammansättningar genom att inkludera elementet <relativeBindForResources> och ange dess enabled attribut i true programkonfigurationsfilen, som du ser i följande exempel.

<configuration>
   <runtime>
      <relativeBindForResources enabled="true" />
   </runtime>
</configuration>

Den optimerade sonden för satellitsammansättningar är en opt-in-funktion. Det vill: Körningen följer de steg som beskrivs i Återställningsprocessen för resurser om inte elementet <relativeBindForResources> finns i programmets konfigurationsfil och dess enabled attribut är inställt på true. I så fall ändras sökningsprocessen för en satellitenhet på följande sätt:

  • Körningstiden använder platsen för den överordnade kodsammansättningen för att söka efter satellitsammansättningen. Om den överordnade sammansättningen är installerad i den globala sammansättningscachen söker körningen i cacheminnet men inte i programmets mapp. Om den överordnade sammansättningen är installerad i en programkatalog söker runtime i programkatalogen men inte i den globala sammansättningscachen.

  • Körningen frågar inte Windows Installer om installation på begäran av satellitsammansättningar.

  • Om avsökningen för en viss resurssammansättning misslyckas genererar inte körmiljön AppDomain.AssemblyResolve händelsen.

Återställningsprocess för .NET Core-resurser

Återställningsprocessen för .NET Core-resurser omfattar följande steg:

  1. Körmiljön försöker läsa in en satellitsammansättning för den begärda kulturen.

    • Söker igenom katalogen för det aktuella programmet efter en underkatalog som matchar den begärda kulturen. Om den hittar underkatalogen söker den i underkatalogen efter en giltig satellitsammansättning för den begärda kulturen och läser in den.

      Anmärkning

      På operativsystem med skiftlägeskänsliga filsystem (det vill säga Linux och macOS) är underkatalogsökningen för kulturnamn skiftlägeskänslig. Underkatalognamnet måste exakt matcha fallet av CultureInfo.Name (till exempel es eller es-MX).

      Anmärkning

      Om programmeraren har härlett en anpassad sammansättningsbelastningskontext från AssemblyLoadContextär situationen komplicerad. Om den exekverande sammansättningen lästes in i den anpassade kontexten laddar körtiden satellitsammansättningen i den anpassade kontexten. Informationen ligger utanför omfånget för det här dokumentet. Se även AssemblyLoadContext.

    • Om en satellitsammansättning inte har hittats, genererar AssemblyLoadContextAssemblyLoadContext.Resolving-händelsen för att indikera att den inte kan hitta satellitsammansättningen. Om du väljer att hantera händelsen kan händelsehanteraren läsa in och returnera en referens till satellitsammansättningen.

    • Om en satellitsammansättning fortfarande inte har hittats gör AssemblyLoadContext att AppDomain utlöser en AppDomain.AssemblyResolve händelse för att indikera att den inte kan hitta satellitsammansättningen. Om du väljer att hantera händelsen kan händelsehanteraren läsa in och returnera en referens till satellitsammansättningen.

  2. Om en satellitsammansättning hittas söker körningsmiljön efter den begärda resursen. Om den hittar resursen i sammansättningen använder den den. Om den inte hittar resursen fortsätter sökningen.

    Anmärkning

    För att hitta en resurs i satellitsammansättningen söker körningen efter resursfilen som begärs av ResourceManager för den aktuella CultureInfo.Name. I resursfilen söker den efter det begärda resursnamnet. Om någon av dem inte hittas behandlas resursen som inte hittad.

  3. Körningssystemet söker därefter igenom de överordnade kulturpaketen genom många möjliga nivåer, där varje gång stegen 1 och 2 upprepas.

    Den överordnade kulturen definieras som en lämplig reservkultur. Överväg föräldrar som reservkandidater, eftersom det är bättre att tillhandahålla en resurs än att kasta ett undantag. Med den här processen kan du också återanvända resurser. Du bör endast ta med en viss resurs på den överordnade nivån om den underordnade kulturen inte behöver lokalisera den begärda resursen. Om du till exempel tillhandahåller satellitsammansättningar för en (neutral engelska), en-GB (engelska som talas i Storbritannien) och en-US (engelska som talas i USA), innehåller satelliten en den gemensamma terminologin, och en-GB satelliterna och en-US tillhandahåller åsidosättningar för endast de termer som skiljer sig åt.

    Varje kultur har bara en överordnad, som definieras av CultureInfo.Parent egenskapen, men en överordnad kan ha sin egen överordnad. Sökningen efter föräldrakulturer stoppas när en kulturs Parent egenskap returnerar CultureInfo.InvariantCulture. För resursåterställning betraktas den invarianta kulturen inte som en överordnad kultur eller en kultur som kan ha resurser.

  4. Om den kultur som ursprungligen angavs och alla föräldrar har genomsökts och resursen fortfarande inte hittas används resursen för standardkulturen (återställning). Vanligtvis ingår resurserna för standardkulturen i huvudprogramsammansättningen. Du kan dock ange värdet Satellite för egenskapen Location för att indikera att den ultimata fallback-platsen för resurserna är en satellitassembly snarare än huvudassembly.

    Anmärkning

    Standardresursen är den enda resurs som kan kompileras med huvudsammansättningen. Om du inte anger en satellitassembly med hjälp av NeutralResourcesLanguageAttribute-attributet är det den sista utvägen (slutliga alternativ). Därför rekommenderar vi att du alltid inkluderar en standarduppsättning med resurser i huvudsammansättningen. Detta förhindrar att undantag utlöses. Genom att inkludera en standardresursfil anger du en reserv för alla resurser och ser till att minst en resurs alltid finns för användaren, även om den inte är kulturellt specifik.

  5. Slutligen, om körtidssystemet inte hittar en resursfil för en standardkultur (återfall) genereras ett MissingManifestResourceException eller MissingSatelliteAssemblyException-undantag för att indikera att resursen inte kunde hittas. Om resursfilen hittas men den begärda resursen inte finns returnerar nullbegäran .

Slutlig reservlösning till satellitstöd

Du kan valfritt ta bort resurserna från huvudsammansättningen och specificera att körmiljön ska läsa in återfallsresurser från en satellitsammansättning som motsvarar en specifik kultur. För att styra återställningsprocessen använder NeutralResourcesLanguageAttribute(String, UltimateResourceFallbackLocation) du konstruktorn och anger ett värde för parametern UltimateResourceFallbackLocation som anger om Resource Manager ska extrahera reservresurserna från huvudsammansättningen eller från en satellitsammansättning.

I följande .NET Framework-exempel används NeutralResourcesLanguageAttribute attributet för att lagra ett programs återställningsresurser i en satellitsammansättning för det franska språket (fr). Exemplet har två textbaserade resursfiler som definierar en enskild strängresurs med namnet Greeting. Den första, resources.fr.txt, innehåller en fransk språkresurs.

Greeting=Bon jour!

För det andra innehåller resurser,ru.txt, en rysk språkresurs.

Greeting=Добрый день

Dessa två filer kompileras till .resources-filer genom att köra Resource File Generator (resgen.exe) från kommandoraden. För den franska språkresursen är kommandot:

resgen.exe resources.fr.txt

För den ryska språkresursen är kommandot:

resgen.exe resources.ru.txt

.resources-filerna bäddas in i dynamiska länkbibliotek genom att köra Assembly Linker (al.exe) från kommandoraden för den franska språkresursen på följande sätt:

al /t:lib /embed:resources.fr.resources /culture:fr /out:fr\Example1.resources.dll

och för den ryska språkresursen enligt följande:

al /t:lib /embed:resources.ru.resources /culture:ru /out:ru\Example1.resources.dll

Programmets källkod finns i en fil med namnet Example1.cs eller Example1.vb. Den innehåller NeutralResourcesLanguageAttribute attributet för att indikera att standardprogramresursen finns i underkatalogen fr. Den instansierar Resource Manager, hämtar värdet för resursen Greeting och visar den för konsolen.

using System;
using System.Reflection;
using System.Resources;

[assembly:NeutralResourcesLanguage("fr", UltimateResourceFallbackLocation.Satellite)]

public class Example
{
   public static void Main()
   {
      ResourceManager rm = new ResourceManager("resources",
                                               typeof(Example).Assembly);
      string greeting = rm.GetString("Greeting");
      Console.WriteLine(greeting);
   }
}
Imports System.Reflection
Imports System.Resources

<Assembly: NeutralResourcesLanguage("fr", UltimateResourceFallbackLocation.Satellite)>
Module Example
    Public Sub Main()
        Dim rm As New ResourceManager("resources", GetType(Example).Assembly)
        Dim greeting As String = rm.GetString("Greeting")
        Console.WriteLine(greeting)
    End Sub
End Module

Du kan sedan kompilera C#-källkoden från kommandoraden på följande sätt:

csc Example1.cs

Kommandot för Visual Basic-kompilatorn är mycket likt:

vbc Example1.vb

Eftersom det inte finns några resurser inbäddade i huvudsammansättningen behöver du inte kompilera med hjälp av växeln /resource .

När du kör exemplet från ett system vars språk är något annat än ryska visas följande utdata:

Bon jour!

Förslag på paketeringsalternativ

Tids- eller budgetbegränsningar kan hindra dig från att skapa en uppsättning resurser för varje underkultur som programmet stöder. I stället kan du skapa en enda satellitsammansättning för en överordnad kultur som alla relaterade subkulturer kan använda. Du kan till exempel ange en enda engelsk satellitsammansättning (en) som hämtas av användare som begär regionspecifika engelska resurser och en enda tysk satellitsammansättning (de) för användare som begär regionspecifika tyska resurser. Till exempel skulle förfrågningar om tyska som talas i Tyskland (de-DE), Österrike (de-AT), och Schweiz (de-CH) falla tillbaka till den tyska satellitenheten (de). Standardresurser är den sista utvägen och bör därför vara de resurser som de flesta av programmets användare kommer att begära, så välj dessa resurser noggrant. Den här metoden distribuerar resurser som är mindre kulturellt specifika, men som avsevärt kan minska programmets lokaliseringskostnader.

Se även