Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
.NET- en Win32-apps en -games worden vaak gelokaliseerd in verschillende talen om hun totale adresseerbare markt uit te breiden. Zie Globalization and localizationvoor meer informatie over de waardepropositie van het lokaliseren van uw app. Door uw .NET- of Win32-app of -game te verpakken als een MSIX- of .appx-pakket, kunt u gebruikmaken van het Resource Management-systeem om app-resources te laden die zijn afgestemd op de runtimecontext. In dit uitgebreide onderwerp worden de technieken beschreven.
Er zijn veel manieren om een traditionele Win32-toepassing te lokaliseren, maar Windows 8 heeft een nieuw systeem voor resourcebeheer geïntroduceerd dat in programmeertalen, in verschillende toepassingstypen werkt en functionaliteit biedt boven en boven eenvoudige lokalisatie. Dit systeem wordt in dit onderwerp aangeduid als 'MRT'. Historisch gezien stond dat voor "Moderne hulpbrontechnologie", maar de term "Modern" wordt niet meer gebruikt. De resourcemanager kan ook wel MRM (Modern Resource Manager) of PRI (Package Resource Index) worden genoemd.
In combinatie met implementatie op basis van MSIX of .appx (bijvoorbeeld uit de Microsoft Store), kan MRT automatisch de meest toepasselijke resources leveren voor een bepaalde gebruiker/apparaat, waardoor de download- en installatiegrootte van uw toepassing wordt geminimaliseerd. Deze groottevermindering kan aanzienlijk zijn voor toepassingen met een grote hoeveelheid gelokaliseerde inhoud, mogelijk op volgorde van meerdere gigabytes voor AAA-games. Extra voordelen van MRT zijn gelokaliseerde vermeldingen in de Windows Shell en de Microsoft Store, automatische terugvallogica wanneer de voorkeurstaal van een gebruiker niet overeenkomt met uw beschikbare resources.
In dit document wordt de architectuur op hoog niveau van MRT beschreven en vindt u een handleiding voor het overzetten van verouderde Win32-toepassingen naar MRT met minimale codewijzigingen. Zodra de overstap naar MRT is gemaakt, zijn er extra voordelen (zoals de mogelijkheid om resources te segmenteren op schaalfactor of systeemthema) beschikbaar voor de ontwikkelaar. Let op: lokalisatie op basis van MRT werkt voor zowel UWP-toepassingen als Win32-toepassingen die worden verwerkt door de Desktop Bridge (ook wel Centennial genoemd).
In veel situaties kunt u uw bestaande lokalisatie-indelingen en broncode blijven gebruiken terwijl u integreert met MRT voor het oplossen van resources tijdens runtime en het minimaliseren van downloadgrootten. Dit is geen alles-of-niets-benadering. De volgende tabel bevat een overzicht van het werk en de geschatte kosten/baten van elke fase. Deze tabel bevat geen niet-lokalisatietaken, zoals het leveren van toepassingspictogrammen met hoge resolutie of hoog contrast. Voor meer informatie over het bieden van meerdere assets voor tegels, pictogrammen, enzovoort, zie Uw resources aanpassen voor taal, schaal, hoog contrast en andere criteria.
| Werk | Voordeel | Geschatte kosten |
|---|---|---|
| Pakketmanifest lokaliseren | Minimaal werk dat vereist is om uw gelokaliseerde inhoud weer te geven in de Windows Shell en in de Microsoft Store | Klein |
| MRT gebruiken om resources te identificeren en te zoeken | Vereisten voor het minimaliseren van download- en installatiegrootten; automatische taalterugval | Gemiddeld |
| Resourcepacks bouwen | Laatste stap om download- en installatiegrootten te minimaliseren | Klein |
| Migreren naar MRT-resourceindelingen en API's | Aanzienlijk kleinere bestandsgrootten (afhankelijk van bestaande resourcetechnologie) | Groot |
Introductie
De meeste niet-triviale toepassingen bevatten elementen van de gebruikersinterface die bekend staan als resources die losgekoppeld zijn van de code van de toepassing (in tegenstelling tot in code vastgelegde waarden die zijn geschreven in de broncode zelf). Er zijn verschillende redenen om de voorkeur te geven aan resources ten opzichte van in code vastgelegde waarden, bijvoorbeeld eenvoudig te bewerken door niet-ontwikkelaars, maar een van de belangrijkste redenen is om de toepassing in staat te stellen verschillende weergaven van dezelfde logische resource tijdens runtime te kiezen. De tekst die moet worden weergegeven op een knop (of de afbeelding die in een pictogram moet worden weergegeven) kan bijvoorbeeld verschillen, afhankelijk van de taal(en) die de gebruiker begrijpt, de kenmerken van het weergaveapparaat of of de gebruiker ondersteunende technologieën heeft ingeschakeld.
Het primaire doel van elke technologie voor resourcebeheer is dus om tijdens runtime een aanvraag voor een logische of symbolische resourcenaam (zoals SAVE_BUTTON_LABEL) te vertalen naar de best mogelijke werkelijke waarde (bijvoorbeeld 'Opslaan') uit een set mogelijke kandidaten (bijvoorbeeld "Opslaan", "Speichern" of "저장"). MRT biedt een dergelijke functie en stelt toepassingen in staat om resourcekandidaten te identificeren met behulp van een groot aantal kenmerken, kwalificatiesgenoemd, zoals de taal van de gebruiker, de weergaveschaalfactor, het geselecteerde thema van de gebruiker en andere omgevingsfactoren. MRT ondersteunt zelfs aangepaste kwalificatieprogramma's voor toepassingen die dit nodig hebben (een toepassing kan bijvoorbeeld verschillende grafische assets bieden voor gebruikers die zijn aangemeld met een account versus gastgebruikers, zonder deze controle expliciet toe te voegen aan elk deel van hun toepassing). MRT werkt met zowel tekenreeksbronnen als bestandsbronnen, waarbij bestandsbronnen worden geïmplementeerd als verwijzingen naar de externe gegevens (de bestanden zelf).
Voorbeeld
Hier volgt een eenvoudig voorbeeld van een toepassing met tekstlabels op twee knoppen (openButton en saveButton) en een PNG-bestand dat wordt gebruikt voor een logo (logoImage). De tekstlabels worden gelokaliseerd in het Engels en Duits en het logo is geoptimaliseerd voor normale bureaubladweergaven (100% schaalfactor) en telefoons met een hoge resolutie (300% schaalfactor). Houd er rekening mee dat dit diagram een conceptueel overzicht van hoog niveau van het model weergeeft; het komt niet precies overeen met de implementatie.
In de afbeelding verwijst de toepassingscode naar de drie namen van logische resources. Tijdens runtime gebruikt de GetResource pseudofunctie MRT om deze resourcenamen in de resourcetabel (bekend als PRI-bestand) te zoeken en de meest geschikte kandidaat te vinden op basis van de omgevingsomstandigheden (de taal van de gebruiker en de schaalfactor van de weergave). In het geval van de labels worden de tekenreeksen rechtstreeks gebruikt. In het geval van de logoafbeelding worden de tekenreeksen geïnterpreteerd als bestandsnamen en worden de bestanden van de schijf gelezen.
Als de gebruiker een andere taal dan Engels of Duits spreekt of een andere weergaveschaalfactor heeft dan 100% of 300%, kiest MRT de 'dichtstbijzijnde' overeenkomende kandidaat op basis van een set terugvalregels (zie Resource Management System voor meer achtergrond).
MRT ondersteunt resources die zijn afgestemd op meer dan één kwalificatie. Bijvoorbeeld, als de logoafbeelding ingebedde tekst bevat die ook moet worden gelokaliseerd, dan heeft het logo vier kandidaten: EN/Scale-100, DE/Scale-100, EN/Scale-300 en DE/Scale-300.
Paragrafen in dit document
In de volgende secties worden de taken op hoog niveau beschreven die nodig zijn om MRT te integreren met uw toepassing.
Fase 0: Een toepassingspakket bouwen
Deze sectie omschrijft hoe u uw huidige bureaubladtoepassing kunt omzetten naar een toepassingspakket. Er worden in deze fase geen MRT-functies gebruikt.
Fase 1: Het toepassingsmanifest lokaliseren
In deze sectie wordt beschreven hoe u het manifest van uw toepassing kunt lokaliseren (zodat dit correct wordt weergegeven in de Windows Shell) terwijl u de verouderde resourceindeling en API nog steeds gebruikt om resources te verpakken en te zoeken.
Fase 2: MRT gebruiken om resources te identificeren en te vinden
In deze sectie wordt beschreven hoe u uw toepassingscode (en mogelijk de indeling van resources) kunt wijzigen om resources te vinden met mrt, terwijl u nog steeds uw bestaande resourceindelingen en API's gebruikt om de resources te laden en te gebruiken.
Fase 3: Resourcepacks bouwen
In deze sectie worden de laatste wijzigingen beschreven die nodig zijn om uw resources te scheiden in afzonderlijke resourcepakketten, waardoor de downloadgrootte (en installatie) van uw app wordt geminimaliseerd.
Niet behandeld in dit document
Nadat fase 0-3 hierboven is voltooid, hebt u een toepassing 'bundel' die kan worden ingediend bij de Microsoft Store en waarmee de download- en installatiegrootte voor gebruikers wordt geminimaliseerd door de resources weg te laten die ze niet nodig hebben (bijvoorbeeld talen die ze niet spreken). Verdere verbeteringen in de grootte en functionaliteit van toepassingen kunnen worden aangebracht door één laatste stap uit te voeren.
Fase 4: Migreren naar MRT-resourceindelingen en API's
Deze fase valt buiten het bereik van dit document; het omvat het verplaatsen van uw resources (met name tekenreeksen) van verouderde formaten, zoals MUI-DLL's of .NET-resourceassemblies, naar PRI-bestanden. Dit kan leiden tot verdere ruimtebesparing voor download- en installatiegrootten. Het maakt ook het gebruik van andere MRT-functies mogelijk, zoals het minimaliseren van het downloaden en installeren van afbeeldingsbestanden op basis van schaalfactor, toegankelijkheidsinstellingen, enzovoort.
Fase 0: Een toepassingspakket bouwen
Voordat u wijzigingen aanbrengt in de resources van uw toepassing, moet u eerst uw huidige verpakkings- en installatietechnologie vervangen door de standaard UWP-verpakkings- en implementatietechnologie. U kunt dit op drie manieren doen:
- Als u een grote bureaubladtoepassing hebt met een complex installatieprogramma of als u veel uitbreidbaarheidspunten van het besturingssysteem gebruikt, kunt u het hulpprogramma Desktop App Converter gebruiken om de INDELING van uw UWP-bestand en manifestgegevens van uw bestaande app-installatieprogramma te genereren (bijvoorbeeld een MSI).
- Als u een kleinere bureaubladtoepassing hebt met relatief weinig bestanden of een eenvoudig installatieprogramma en geen uitbreidbaarheidshaken, kunt u de bestandsindeling en manifestgegevens handmatig maken.
- Als u opnieuw bouwt vanaf de bron en uw app wilt bijwerken als een pure UWP-toepassing, kunt u een nieuw project maken in Visual Studio en vertrouwen op de IDE om veel van het werk voor u uit te voeren.
Als u het Desktop App Converter-wilt gebruiken, raadpleegt u Een bureaubladtoepassing verpakken met behulp van het desktop-app-conversieprogramma voor meer informatie over het conversieproces. Een volledige set Desktop Converter-voorbeelden vindt u op de Desktop Bridge naar UWP-voorbeelden gitHub-opslagplaats.
Opmerking
Het Desktop App Converter is verouderd verklaard. Gebruik het nieuwe en verbeterde MSIX Packaging Tool om uw bureaublad-apps te verpakken.
Als u het pakket handmatig wilt maken, moet u een mapstructuur maken die alle bestanden van uw toepassing bevat (uitvoerbare bestanden en inhoud, maar niet broncode) en een pakketmanifestbestand (.appxmanifest). Een voorbeeld is te vinden in het Hello, World GitHub-voorbeeld, maar een basispakketmanifestbestand dat het bureaubladprogramma met de naam ContosoDemo.exe uitvoert, is als volgt, waarbij de gemarkeerde tekst wordt vervangen door uw eigen waarden.
<?xml version="1.0" encoding="utf-8" ?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
<Identity Name="Contoso.Demo"
Publisher="CN=Contoso.Demo"
Version="1.0.0.0" />
<Properties>
<DisplayName>Contoso App</DisplayName>
<PublisherDisplayName>Contoso, Inc</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0"
MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="en-US" />
</Resources>
<Applications>
<Application Id="ContosoDemo" Executable="ContosoDemo.exe"
EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="Contoso Demo" BackgroundColor="#777777"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="Contoso Demo">
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
Zie App-pakketmanifestvoor meer informatie over het pakketmanifestbestand en de pakketindeling.
Als u Visual Studio gebruikt om een nieuw project te maken en uw bestaande code over te brengen, raadpleegt u Een 'Hallo wereld'-app maken. U kunt uw bestaande code opnemen in het nieuwe project, maar waarschijnlijk moet u belangrijke codewijzigingen aanbrengen (met name in de gebruikersinterface) om te worden uitgevoerd als een pure UWP-app. Deze wijzigingen vallen buiten het bereik van dit document.
Fase 1: Het manifest lokaliseren
Stap 1.1: Tekenreeksen en assets bijwerken in het manifest
In fase 0 hebt u een basispakketmanifestbestand (.appxmanifest) gemaakt voor uw toepassing (op basis van de waarden die zijn opgegeven voor het conversieprogramma, geëxtraheerd uit het MSI- of handmatig ingevoerd in het manifest), maar bevat deze geen gelokaliseerde informatie, noch biedt het ondersteuning voor aanvullende functies zoals tegelassets met een hoge resolutie, enzovoort.
Om ervoor te zorgen dat de naam en beschrijving van uw toepassing correct zijn gelokaliseerd, moet u bepaalde resources in een set resourcebestanden definiëren en het pakketmanifest bijwerken om ernaar te verwijzen.
Een standaardresourcebestand maken
De eerste stap is het maken van een standaardresourcebestand in uw standaardtaal (bijvoorbeeld Amerikaans Engels). U kunt dit handmatig doen met een teksteditor of via Resource Designer in Visual Studio.
Als u de resources handmatig wilt maken:
- Maak een XML-bestand met de naam
resources.reswen plaats het in eenStrings\en-ussubmap van uw project. Gebruik de juiste BCP-47-code als uw standaardtaal geen Amerikaans Engels is. - Voeg in het XML-bestand de volgende inhoud toe, waarbij de gemarkeerde tekst wordt vervangen door de juiste tekst voor uw app, in uw standaardtaal.
Opmerking
Er gelden beperkingen voor de lengte van sommige van deze tekenreeksen. Zie VisualElementsvoor meer informatie.
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ApplicationDescription">
<value>Contoso Demo app with localized resources (English)</value>
</data>
<data name="ApplicationDisplayName">
<value>Contoso Demo Sample (English)</value>
</data>
<data name="PackageDisplayName">
<value>Contoso Demo Package (English)</value>
</data>
<data name="PublisherDisplayName">
<value>Contoso Samples, USA</value>
</data>
<data name="TileShortName">
<value>Contoso (EN)</value>
</data>
</root>
Als u de ontwerpfunctie in Visual Studio wilt gebruiken:
- Maak de
Strings\en-usmap (of een andere taal indien van toepassing) in uw project en voeg een Nieuw item toe aan de hoofdmap van uw project, met behulp van de standaardnaam vanresources.resw. Zorg ervoor dat u resourcesbestand (.resw) kiest en niet resourcewoordenlijst. Een resourcewoordenlijst is een bestand dat wordt gebruikt door XAML-toepassingen. - Voer met behulp van de ontwerpfunctie de volgende tekenreeksen in (gebruik dezelfde
Namesmaar vervang deValuesdoor de juiste tekst voor uw toepassing):
Opmerking
Als u begint met de Visual Studio-ontwerpfunctie, kunt u de XML altijd rechtstreeks bewerken door op F7te drukken. Maar als u begint met een minimaal XML-bestand, herkent de ontwerper het bestand niet omdat er veel extra metagegevens ontbreken; U kunt dit oplossen door de XSD-gegevens van een door de ontwerper gegenereerd bestand naar uw met de hand bewerkte XML-bestand te kopiëren.
Het manifest bijwerken om te verwijzen naar de resources
Nadat u de waarden hebt gedefinieerd in het bestand .resw, moet u het manifest bijwerken om te verwijzen naar de resourcereeksen. Ook hier kunt u een XML-bestand rechtstreeks bewerken of afhankelijk zijn van de Visual Studio Manifest Designer.
Als u XML rechtstreeks bewerkt, opent u het AppxManifest.xml bestand en voert u de volgende wijzigingen aan in de gemarkeerde waarden. Gebruik deze exacte tekst, niet specifiek voor uw toepassing. U hoeft deze exacte resourcenamen niet te gebruiken, maar u kunt zelf kiezen, maar wat u ook kiest, moet exact overeenkomen met wat er in het .resw bestand staat. Deze namen moeten overeenkomen met de Names die u in het .resw-bestand hebt gemaakt, voorafgegaan door het ms-resource:-schema en de Resources/-naamruimte.
Opmerking
Veel elementen van het manifest zijn weggelaten uit dit fragment - verwijder niets!
<?xml version="1.0" encoding="utf-8"?>
<Package>
<Properties>
<DisplayName>ms-resource:Resources/PackageDisplayName</DisplayName>
<PublisherDisplayName>ms-resource:Resources/PublisherDisplayName</PublisherDisplayName>
</Properties>
<Applications>
<Application>
<uap:VisualElements DisplayName="ms-resource:Resources/ApplicationDisplayName"
Description="ms-resource:Resources/ApplicationDescription">
<uap:DefaultTile ShortName="ms-resource:Resources/TileShortName">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo" />
</uap:ShowNameOnTiles>
</uap:DefaultTile>
</uap:VisualElements>
</Application>
</Applications>
</Package>
Als u de visual Studio-manifestontwerper gebruikt, opent u het .appxmanifest-bestand en wijzigt u de gemarkeerde waarden waarden op het tabblad *Application en het tabblad Packaging:
Stap 1.2: EEN PRI-bestand bouwen, een MSIX-pakket maken en controleren of het werkt
U moet nu het .pri-bestand kunnen bouwen en de toepassing implementeren om te controleren of de juiste informatie (in uw standaardtaal) wordt weergegeven in het menu Start.
Als u in Visual Studio bouwt, drukt u op Ctrl+Shift+B om het project te bouwen en klikt u met de rechtermuisknop op het project en kiest u Deploy in het snelmenu.
Als u handmatig bouwt, volgt u deze stappen om een configuratiebestand te maken voor MakePRI hulpprogramma en om het .pri bestand zelf te genereren (meer informatie vindt u in Handmatige app-verpakking):
Open een opdrachtprompt voor ontwikkelaars vanuit de map Visual Studio 2019 of Visual Studio 2022 in het menu Start.
Schakel over naar de hoofdmap van het project (de map die het .appxmanifest-bestand en de Tekenreeksen map bevat).
Typ de volgende opdracht, waarbij u "contoso_demo.xml" vervangt door een naam die geschikt is voor uw project en "en-US" door de standaardtaal van uw app (of zorg ervoor dat deze en-US indien van toepassing). Let op: het XML-bestand wordt gemaakt in de bovenliggende map (niet in de projectmap) omdat het geen deel uitmaakt van de toepassing (u kunt elke andere map kiezen die u wilt gebruiken, maar zorg ervoor dat u dat in toekomstige opdrachten vervangt).
makepri createconfig /cf ..\contoso_demo.xml /dq en-US /pv 10.0 /oU kunt
makepri createconfig /?typen om te zien wat elke parameter doet, maar in het kort:-
/cfstelt de bestandsnaam van de configuratie in (de uitvoer van deze opdracht) -
/dqstelt de standaardkwalificaties in, in dit geval de taalen-US -
/pvstelt de platformversie in, in dit geval Windows 10 -
/ostelt dit in om het uitvoerbestand te overschrijven als het bestaat
-
Nu u een configuratiebestand hebt, voert u
MakePRIopnieuw uit om daadwerkelijk naar de schijf te zoeken naar resources en deze in een PRI-bestand te verpakken. Vervang "contoso_demop.xml" door de XML-bestandsnaam die u in de vorige stap hebt gebruikt en zorg ervoor dat u de hoofdmap opgeeft voor zowel invoer als uitvoer.makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /oU kunt
makepri new /?typen om te zien wat elke parameter doet, maar in een notendop:-
/prstelt de hoofdmap van het project in (in dit geval de huidige map) -
/cfstelt de configuratiebestandsnaam in, gemaakt in de vorige stap -
/ofhet uitvoerbestand instellen -
/mfmaakt een mappingbestand (zodat we bestanden in het pakket in een latere stap kunnen uitsluiten) -
/ostelt dit in om het uitvoerbestand te overschrijven als het bestaat
-
U hebt nu een
.pribestand met de standaardtaalresources (bijvoorbeeld en-US). Als u wilt controleren of deze correct werkt, kunt u de volgende opdracht uitvoeren:makepri dump /if ..\resources.pri /of ..\resources /oU kunt
makepri dump /?typen om te zien wat elke parameter doet, maar in een notendop:-
/ifstelt de invoerbestandsnaam in -
/ofstelt de uitvoerbestandsnaam in (.xmlwordt automatisch toegevoegd) -
/ostelt dit in om het uitvoerbestand te overschrijven als het bestaat
-
Ten slotte kunt u
..\resources.xmlopenen in een teksteditor en controleren of uw<NamedResource>waarden (zoalsApplicationDescriptionenPublisherDisplayName) worden vermeld, samen met<Candidate>waarden voor de door u gekozen standaardtaal (er is nog andere inhoud aan het begin van het bestand; negeer dat voorlopig).
U kunt het toewijzingsbestand openen ..\resources.map.txt om te controleren of het de bestanden bevat die nodig zijn voor uw project (inclusief het PRI-bestand, dat geen deel uitmaakt van de map van het project). Belangrijk: het toewijzingsbestand niet een verwijzing naar het resources.resw-bestand bevatten omdat de inhoud van dat bestand al is ingesloten in het PRI-bestand. Deze bevat echter andere resources, zoals de bestandsnamen van uw afbeeldingen.
Het pakket bouwen en ondertekenen
Nu het PRI-bestand is gebouwd, kunt u het pakket bouwen en ondertekenen:
Als u het app-pakket wilt maken, voert u de volgende opdracht uit om
contoso_demo.appxte vervangen door de naam van het .msix/.appx-bestand dat u wilt maken en ervoor te zorgen dat u een andere map voor het bestand kiest (in dit voorbeeld wordt de bovenliggende map gebruikt; het kan overal zijn, maar moet niet de projectmap zijn).makeappx pack /m AppXManifest.xml /f ..\resources.map.txt /p ..\contoso_demo.appx /oU kunt
makeappx pack /?typen om te zien wat elke parameter doet, maar in een notendop:-
/mstelt het manifestbestand in voor gebruik -
/fstelt het configuratiebestand in dat moet worden gebruikt (aangemaakt in de vorige stap) -
/pde naam van het uitvoerpakket instellen -
/ostelt dit in om het uitvoerbestand te overschrijven als het bestaat
-
Nadat het pakket is gemaakt, moet het ondertekend worden. De eenvoudigste manier om een handtekeningcertificaat op te halen is door een leeg Universeel Windows-project te maken in Visual Studio en het
.pfxbestand te kopiëren dat het maakt, maar u kunt er handmatig een maken met behulp van deMakeCertenPvk2Pfxhulpprogramma's, zoals beschreven in Een certificaat voor app-pakketondertekening maken.Belangrijk
Als u handmatig een handtekeningcertificaat maakt, moet u ervoor zorgen dat u de bestanden in een andere map plaatst dan uw bronproject of de pakketbron, anders wordt het mogelijk opgenomen als onderdeel van het pakket, inclusief de persoonlijke sleutel.
Gebruik de volgende opdracht om het pakket te ondertekenen. Houd er rekening mee dat de
Publisherdie is opgegeven in hetIdentityelement van deAppxManifest.xmlovereenkomen met deSubjectvan het certificaat (dit is niet het<PublisherDisplayName>-element, de gelokaliseerde weergavenaam die aan gebruikers moet worden weergegeven). Vervang zoals gebruikelijk decontoso_demo...bestandsnamen door de namen die geschikt zijn voor uw project en (zeer belangrijk) zorg ervoor dat het.pfxbestand zich niet in de huidige map bevindt (anders zou het zijn gemaakt als onderdeel van uw pakket, inclusief de persoonlijke ondertekeningssleutel!):signtool sign /fd SHA256 /a /f ..\contoso_demo_key.pfx ..\contoso_demo.appxU kunt
signtool sign /?typen om te zien wat elke parameter doet, maar in een notendop:-
/fdstelt het algoritme File Digest (SHA256 is de standaardinstelling voor .appx) -
/aselecteert automatisch het beste certificaat -
/fgeeft het invoerbestand op dat het handtekeningcertificaat bevat
-
Ten slotte kunt u nu dubbelklikken op het .appx-bestand om het te installeren, of als u liever de opdrachtregel gebruikt, kunt u een PowerShell-prompt openen, de map met het pakket wijzigen en het volgende typen (waarbij u contoso_demo.appx vervangt door uw pakketnaam):
add-appxpackage contoso_demo.appx
Als u fouten ontvangt over het certificaat dat niet wordt vertrouwd, controleert u of het wordt toegevoegd aan het computerarchief (niet het gebruikersarchief). Als u het certificaat wilt toevoegen aan de certificatenopslag van de computer, kunt u de commandoregel of Windows Verkenner gebruiken.
Om de opdrachtregel te gebruiken:
Voer een opdrachtprompt van Visual Studio 2019 of Visual Studio 2022 uit als beheerder.
Ga naar de map met het
.cer-bestand (zorg ervoor dat dit zich buiten uw bron- of projectmappen bevindt!)Typ de volgende opdracht en vervang
contoso_demo.cerdoor uw bestandsnaam:certutil -addstore TrustedPeople contoso_demo.cerU kunt
certutil -addstore /?uitvoeren om te zien wat elke parameter doet, maar in een notendop:-
-addstoreeen certificaat toevoegen aan een certificaatarchief -
TrustedPeoplegeeft het archief aan waarin het certificaat is geplaatst
-
Windows Verkenner gebruiken:
- Navigeer naar de map met het
.pfx-bestand - Dubbelklik op het
.pfxbestand en de wizard Certificaat importeren moet worden weergegeven - Kies
Local Machineen klik opNext - Accepteer de gebruikersaccountbeheer prompt voor admin elevatie als deze verschijnt, en klik op
Next - Voer het wachtwoord voor de persoonlijke sleutel in als er een is en klik op
Next - Selecteer
Place all certificates in the following store - Klik op
Browseen kies de mapTrusted People(niet Vertrouwde uitgevers) - Klik op
Nexten klik vervolgens opFinish
Nadat u het certificaat hebt toegevoegd aan de Trusted People opslag, probeert u het pakket opnieuw te installeren.
U ziet nu dat uw app wordt weergegeven in de lijst 'Alle apps' van het startmenu, met de juiste informatie uit het .resw / .pri-bestand. Als u een lege tekenreeks of de tekenreeks ms-resource:... ziet, is er iets misgegaan. Controleer de bewerkingen opnieuw en controleer of deze juist zijn. Als u met de rechtermuisknop op uw app klikt in het menu Start, kunt u deze vastmaken als tegel en controleren of de juiste informatie daar ook wordt weergegeven.
Stap 1.3: Meer ondersteunde talen toevoegen
Nadat de wijzigingen zijn aangebracht in het pakketmanifest en het eerste resources.resw-bestand is gemaakt, is het toevoegen van extra talen eenvoudig.
Aanvullende gelokaliseerde resources maken
Maak eerst de aanvullende gelokaliseerde resourcewaarden.
Maak in de Strings map extra mappen voor elke taal die u ondersteunt met behulp van de juiste BCP-47-code (bijvoorbeeld Strings\de-DE). Maak in elk van deze mappen een resources.resw bestand (met behulp van een XML-editor of de Visual Studio-ontwerper) die de vertaalde resourcewaarden bevat. Er wordt van uitgegaan dat u al de gelokaliseerde tekenreeksen ergens hebt en dat u ze alleen naar het .resw-bestand moet kopiëren; dit document heeft geen betrekking op de vertaalstap zelf.
Het Strings\de-DE\resources.resw bestand ziet er bijvoorbeeld als volgt uit, waarbij de gemarkeerde tekst is gewijzigd van en-US:
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ApplicationDescription">
<value>Contoso Demo app with localized resources (German)</value>
</data>
<data name="ApplicationDisplayName">
<value>Contoso Demo Sample (German)</value>
</data>
<data name="PackageDisplayName">
<value>Contoso Demo Package (German)</value>
</data>
<data name="PublisherDisplayName">
<value>Contoso Samples, DE</value>
</data>
<data name="TileShortName">
<value>Contoso (DE)</value>
</data>
</root>
In de volgende stappen wordt ervan uitgegaan dat u resources hebt toegevoegd voor zowel de-DE als fr-FR, maar hetzelfde patroon kan worden gevolgd voor elke taal.
Het pakketmanifest bijwerken om ondersteunde talen weer te geven
Het pakketmanifest moet worden bijgewerkt om de talen weer te geven die door de app worden ondersteund. Het conversieprogramma voor bureaublad-apps voegt de standaardtaal toe, maar de andere moeten expliciet worden toegevoegd. Als u het AppxManifest.xml bestand rechtstreeks bewerkt, werkt u het Resources knooppunt als volgt bij, voegt u zoveel elementen toe als u nodig hebt en vervangt u de juiste talen die u ondersteunt en zorgt u ervoor dat het eerste item in de lijst de standaardtaal (terugvaltaal) is.
In dit voorbeeld is de standaardinstelling Engels (VS) met extra ondersteuning voor zowel Duits (Duitsland) als Frans (Frankrijk):
<Resources>
<Resource Language="EN-US" />
<Resource Language="DE-DE" />
<Resource Language="FR-FR" />
</Resources>
Als u Visual Studio gebruikt, hoeft u niets te doen; als u naar Package.appxmanifest kijkt, ziet u de speciale x-genereren waarde, waardoor het buildproces de talen invoegt die in uw project worden gevonden (op basis van de mappen met BCP-47-codes). Houd er rekening mee dat dit geen geldige waarde is voor een echt pakketmanifest; Het werkt alleen voor Visual Studio-projecten:
<Resources>
<Resource Language="x-generate" />
</Resources>
Opnieuw bouwen met de gelokaliseerde waarden
Nu kunt u uw toepassing bouwen en implementeren. Als u uw taalvoorkeur wijzigt in Windows, ziet u dat de nieuw gelokaliseerde waarden worden weergegeven in het menu Start (instructies voor het wijzigen van uw taal vindt u hieronder).
Voor Visual Studio kunt u nogmaals Ctrl+Shift+B gebruiken om te bouwen en met de rechtermuisknop op het project te klikken om Deploy.
Als u het project handmatig bouwt, volgt u dezelfde stappen als hierboven, maar voegt u de extra talen, gescheiden door onderstrepingstekens, toe aan de standaardkwalificatielijst (/dq) bij het maken van het configuratiebestand. Als u bijvoorbeeld de Resources Engels, Duits en Frans wilt ondersteunen die in de vorige stap zijn toegevoegd:
makepri createconfig /cf ..\contoso_demo.xml /dq en-US_de-DE_fr-FR /pv 10.0 /o
Hiermee maakt u een PRI-bestand met alle opgegeven talen die u eenvoudig kunt gebruiken voor het testen. Als de totale grootte van uw middelen klein is of als u slechts een klein aantal talen ondersteunt, kan dit acceptabel zijn voor uw verzendapp. Het is alleen wanneer u gebruik wilt maken van de voordelen van het verkleinen van de installatie-/downloadgrootte voor uw middelen, dat u extra werk moet verrichten om afzonderlijke taalpakketten te bouwen.
Testen met de gelokaliseerde waarden
Als u de nieuwe gelokaliseerde wijzigingen wilt testen, voegt u een nieuwe voorkeurstaal voor de gebruikersinterface toe aan Windows. U hoeft geen taalpakketten te downloaden, het systeem opnieuw op te starten of uw volledige Windows-gebruikersinterface in een vreemde taal weer te geven.
- De
Settings-app (Windows + I) uitvoeren - Ga naar
Time & language - Ga naar
Region & language - Klik op
Add a language - Typ (of selecteer) de gewenste taal (bijvoorbeeld
Deutsch)German- Als er subtalen zijn, kiest u de gewenste taal (bijvoorbeeld
Deutsch / Deutschland)
- Als er subtalen zijn, kiest u de gewenste taal (bijvoorbeeld
- Selecteer de nieuwe taal in de taallijst
- Klik op
Set as default
Open nu het startmenu en zoek naar uw toepassing. U ziet nu de gelokaliseerde waarden voor de geselecteerde taal (andere apps worden mogelijk ook gelokaliseerd weergegeven). Als u de gelokaliseerde naam niet meteen ziet, wacht u enkele minuten totdat de cache van het startmenu is vernieuwd. Als u wilt terugkeren naar uw systeemeigen taal, moet u deze de standaardtaal in de taallijst maken.
Stap 1.4: Meer onderdelen van het pakketmanifest lokaliseren (optioneel)
Andere secties van het pakketmanifest kunnen worden gelokaliseerd. Als uw toepassing bijvoorbeeld bestandsextensies verwerkt, moet deze een windows.fileTypeAssociation extensie in het manifest hebben, met behulp van de groen gemarkeerde tekst precies zoals wordt weergegeven (omdat deze naar resources verwijst) en de geel gemarkeerde tekst vervangen door informatie die specifiek is voor uw toepassing:
<Extensions>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="default">
<uap:DisplayName>ms-resource:Resources/FileTypeDisplayName</uap:DisplayName>
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
<uap:InfoTip>ms-resource:Resources/FileTypeInfoTip</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType ContentType="application/x-contoso">.contoso</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
</Extensions>
U kunt deze informatie ook toevoegen met behulp van Visual Studio Manifest Designer, met behulp van het tabblad Declarations, waarbij u de gemarkeerde waarden van de noteert:
Voeg nu de bijbehorende resourcenamen toe aan elk van uw .resw-bestanden, waarbij u de gemarkeerde tekst vervangt door de juiste tekst voor uw app (vergeet niet dit te doen voor elke ondersteunde taal!):
... existing content...
<data name="FileTypeDisplayName">
<value>Contoso Demo File</value>
</data>
<data name="FileTypeInfoTip">
<value>Files used by Contoso Demo App</value>
</data>
Dit wordt in delen van de Windows-shell, zoals Verkenner, vervolgens weergegeven:
Bouw het pakket en test het net als voorheen, waarbij nieuwe scenario's worden uitgevoerd die de nieuwe UI-tekenreeksen moeten weergeven.
Fase 2: MRT gebruiken om resources te identificeren en te vinden
In de vorige sectie hebt u laten zien hoe u MRT gebruikt om het manifestbestand van uw app te lokaliseren, zodat de Windows Shell de naam en andere metagegevens van de app correct kan weergeven. Hiervoor zijn geen codewijzigingen vereist; het vereist gewoon het gebruik van .resw bestanden en een aantal extra hulpprogramma's. In deze sectie ziet u hoe u MRT gebruikt om resources te vinden in uw bestaande resourceindelingen en hoe u uw bestaande code voor het afhandelen van resources gebruikt met minimale wijzigingen.
Veronderstellingen over bestaande bestandsindeling en toepassingscode
Omdat er veel manieren zijn om Win32 Desktop-apps te lokaliseren, maakt dit document enkele vereenvoudigende veronderstellingen over de structuur van de bestaande toepassing die u moet toewijzen aan uw specifieke omgeving. Mogelijk moet u enkele wijzigingen aanbrengen in uw bestaande codebasis of resource-indeling om te voldoen aan de vereisten van MRT. Deze zijn grotendeels buiten het bereik van dit document.
Indeling van resourcebestand
In dit artikel wordt ervan uitgegaan dat uw gelokaliseerde resources allemaal dezelfde bestandsnamen hebben (bijvoorbeeld contoso_demo.exe.mui of contoso_strings.dll of contoso.strings.xml) maar dat ze in verschillende mappen worden geplaatst met BCP-47-namen (en-US, de-DE, enzovoort). Het maakt niet uit hoeveel resourcebestanden u hebt, wat hun namen zijn, wat hun bestandsindelingen /bijbehorende API's zijn, enzovoort. Het enige wat van belang is, is dat elke logische resource dezelfde bestandsnaam heeft (maar in een andere fysieke map is geplaatst).
Als een tegenvoorbeeld: als uit uw toepassing een platte bestandsstructuur gebruikt met een enkele Resources-map waarin de bestanden english_strings.dll en french_strings.dllzich bevinden, zou deze niet goed passen bij MRT. Een betere structuur is een Resources map met submappen en bestanden en\strings.dll en fr\strings.dll. Het is ook mogelijk om dezelfde basisbestandsnaam te gebruiken, maar met ingesloten kwalificaties, zoals strings.lang-en.dll en strings.lang-fr.dll, maar het gebruik van mappen met de taalcodes is conceptueel eenvoudiger, dus het is waar we ons op richten.
Opmerking
Het is nog steeds mogelijk om MRT en de voordelen van verpakking te gebruiken, zelfs als u deze naamconventie voor bestanden niet kunt volgen; Het vereist gewoon meer werk.
De toepassing kan bijvoorbeeld een set aangepaste UI-opdrachten (gebruikt voor knoplabels enzovoort) hebben in een eenvoudig tekstbestand met de naam ui.txt, ingedeeld onder een UICommands map:
+ ProjectRoot |--+ Strings | |--+ en-US | | \--- resources.resw | \--+ de-DE | \--- resources.resw |--+ UICommands | |--+ en-US | | \--- ui.txt | \--+ de-DE | \--- ui.txt |--- AppxManifest.xml |--- ...rest of project...
Code voor het laden van resources
In dit artikel wordt ervan uitgegaan dat u op een bepaald moment in uw code het bestand wilt zoeken dat een gelokaliseerde resource bevat, laadt en vervolgens gebruikt. De API's die worden gebruikt om de resources te laden, de API's die worden gebruikt om de resources te extraheren, enzovoort, zijn niet belangrijk. In pseudocode zijn er in feite drie stappen:
set userLanguage = GetUsersPreferredLanguage()
set resourceFile = FindResourceFileForLanguage(MY_RESOURCE_NAME, userLanguage)
set resource = LoadResource(resourceFile)
// now use 'resource' however you want
MRT vereist alleen het wijzigen van de eerste twee stappen in dit proces: hoe u de beste kandidaat-resources bepaalt en hoe u ze vindt. Hiervoor hoeft u niet te wijzigen hoe u de resources laadt of gebruikt (hoewel dit faciliteiten biedt als u hiervan gebruik wilt maken).
De toepassing kan bijvoorbeeld gebruikmaken van de Win32-API-GetUserPreferredUILanguages, de functie CRT sprintfen de Win32-API CreateFile om de drie pseudocodefuncties hierboven te vervangen en vervolgens handmatig het tekstbestand te parseren op zoek naar name=value paren. (De details zijn niet belangrijk; dit is slechts om te illustreren dat MRT geen invloed heeft op de technieken die worden gebruikt voor het verwerken van resources zodra ze zijn gelokaliseerd).
Stap 2.1: Codewijzigingen voor het gebruik van MRT om bestanden te vinden
Het is niet moeilijk om uw code aan te passen naar het gebruik van MRT voor het vinden van resources. Hiervoor moet u een handvol WinRT-typen en een paar regels code gebruiken. De belangrijkste typen die u gaat gebruiken, zijn als volgt:
- ResourceContext, waarin de huidige actieve set kwalificatiewaarden (taal, schaalfactor, enzovoort) wordt ingekapseld.
- ResourceManager (de WinRT-versie, niet de .NET-versie), waarmee u toegang hebt tot alle resources uit het PRI-bestand
- ResourceMap, die een specifieke subset vertegenwoordigt van de resources in het PRI-bestand (in dit voorbeeld de op bestanden gebaseerde resources versus de tekenreeksresources)
- NamedResource, die een logische bron en al zijn mogelijke kandidaten vertegenwoordigt
- ResourceCandidate, die één concrete kandidaatresource vertegenwoordigt
In pseudocode is de manier waarop u een bepaalde resourcebestandsnaam (zoals UICommands\ui.txt in het bovenstaande voorbeeld) als volgt kunt oplossen:
// Get the ResourceContext that applies to this app
set resourceContext = ResourceContext.GetForViewIndependentUse()
// Get the current ResourceManager (there's one per app)
set resourceManager = ResourceManager.Current
// Get the "Files" ResourceMap from the ResourceManager
set fileResources = resourceManager.MainResourceMap.GetSubtree("Files")
// Find the NamedResource with the logical filename we're looking for,
// by indexing into the ResourceMap
set desiredResource = fileResources["UICommands\ui.txt"]
// Get the ResourceCandidate that best matches our ResourceContext
set bestCandidate = desiredResource.Resolve(resourceContext)
// Get the string value (the filename) from the ResourceCandidate
set absoluteFileName = bestCandidate.ValueAsString
Houd er met name rekening mee dat de code geen een specifieke taalmap aanvraagt, zoals UICommands\en-US\ui.txt, ook al bestaan de bestanden op schijf. In plaats daarvan vraagt het om de logische bestandsnaam UICommands\ui.txt en is het afhankelijk van MRT om het juiste on-disk-bestand te vinden in een van de taalmappen.
Vanaf hier kan de voorbeeld-app CreateFile blijven gebruiken om de absoluteFileName te laden en de name=value paren net als voorheen te parseren; deze logica hoeft niet te worden gewijzigd in de app. Als u in C# of C++/CX schrijft, is de werkelijke code niet veel ingewikkelder dan dit (en in feite kunnen veel tussenliggende variabelen worden verwijderd) - zie de sectie over .NET-resources ladenhieronder. C++/WRL-toepassingen zijn complexer vanwege de com-gebaseerde COM-api's op laag niveau die worden gebruikt om de WinRT-API's te activeren en aan te roepen, maar de fundamentele stappen die u uitvoert, zijn hetzelfde: zie de sectie over Win32 MUI-resources laden, hieronder.
.NET-resources laden
Omdat .NET een ingebouwd mechanisme heeft voor het zoeken en laden van resources (ook wel 'Satellietassembly's genoemd), is er geen expliciete code die moet worden vervangen zoals in het bovenstaande synthetische voorbeeld. In .NET hebt u alleen uw resource-DLL's nodig in de juiste mappen en bevinden ze zich automatisch voor u. Wanneer een app is verpakt als een MSIX of .appx met behulp van resourcepakketten, is de mapstructuur enigszins anders. In plaats van dat de resourcemappen submappen van de hoofdmap van de toepassing zijn, staan ze op hetzelfde niveau. Als de gebruiker de taal niet in zijn voorkeuren heeft staan, zijn de resourcemappen mogelijk helemaal niet aanwezig.
Stel u een .NET-toepassing voor met de volgende indeling, waarbij alle bestanden onder de map MainApp staan:
+ MainApp |--+ en-us | \--- MainApp.resources.dll |--+ de-de | \--- MainApp.resources.dll |--+ fr-fr | \--- MainApp.resources.dll \--- MainApp.exe
Na de conversie naar .appx ziet de indeling er ongeveer als volgt uit, ervan uitgaande dat en-US de standaardtaal was en de gebruiker zowel Duits als Frans heeft vermeld in de taallijst:
+ WindowsAppsRoot |--+ MainApp_neutral | |--+ en-us | | \--- MainApp.resources.dll | \--- MainApp.exe |--+ MainApp_neutral_resources.language_de | \--+ de-de | \--- MainApp.resources.dll \--+ MainApp_neutral_resources.language_fr \--+ fr-fr \--- MainApp.resources.dll
Omdat de gelokaliseerde resources niet meer voorkomen in submappen onder de installatielocatie van het hoofdbestand, mislukt de ingebouwde .NET-resourceomzetting. Gelukkig heeft .NET een goed gedefinieerd mechanisme voor het verwerken van mislukte assemblybelastingspogingen: de AssemblyResolve gebeurtenis. Een .NET-app met behulp van MRT moet zich registreren voor deze gebeurtenis en de ontbrekende assembly voor het .NET-resourcesubsysteem opgeven.
Een beknopt voorbeeld van het gebruik van de WinRT-API's voor het vinden van satellietassembly's die door .NET worden gebruikt, is als volgt; de code zoals deze wordt gepresenteerd, wordt opzettelijk gecomprimeerd om een minimale implementatie weer te geven, hoewel u kunt zien dat deze nauw is toegewezen aan de pseudocode hierboven, waarbij de doorgegeven ResolveEventArgs de naam van de assembly opgeeft die we moeten vinden. Een uitvoerbare versie van deze code (met gedetailleerde opmerkingen en foutafhandeling) vindt u in het bestand PriResourceRsolver.cs in de .NET Assembly Resolver voorbeeld op GitHub.
static class PriResourceResolver
{
internal static Assembly ResolveResourceDll(object sender, ResolveEventArgs args)
{
var fullAssemblyName = new AssemblyName(args.Name);
var fileName = string.Format(@"{0}.dll", fullAssemblyName.Name);
var resourceContext = ResourceContext.GetForViewIndependentUse();
resourceContext.Languages = new[] { fullAssemblyName.CultureName };
var resource = ResourceManager.Current.MainResourceMap.GetSubtree("Files")[fileName];
// Note use of 'UnsafeLoadFrom' - this is required for apps installed with .appx, but
// in general is discouraged. The full sample provides a safer wrapper of this method
return Assembly.UnsafeLoadFrom(resource.Resolve(resourceContext).ValueAsString);
}
}
Gezien de bovenstaande klasse voegt u het volgende ergens vroeg toe in de opstartcode van uw toepassing (voordat gelokaliseerde resources moeten worden geladen):
void EnableMrtResourceLookup()
{
AppDomain.CurrentDomain.AssemblyResolve += PriResourceResolver.ResolveResourceDll;
}
De .NET-runtime genereert de AssemblyResolve gebeurtenis wanneer deze de resource-DLL's niet kan vinden, waarna de opgegeven gebeurtenis-handler het gewenste bestand zoekt via MRT en de assembly retourneert.
Opmerking
Als uw app al een AssemblyResolve handler voor andere doeleinden heeft, moet u de resource-oplossingscode integreren met uw bestaande code.
Win32 MUI-resources aan het laden
Het laden van Win32 MUI-resources is in feite hetzelfde als het laden van .NET-satellietassembly's, maar dan met C++/CX- of C++/WRL-code. Met C++/CX kunt u veel eenvoudigere code gebruiken die nauw overeenkomt met de bovenstaande C#-code, maar maakt gebruik van C++-taalextensies, compilerswitches en extra runtime-overheard die u mogelijk wilt vermijden. Als dat het geval is, biedt het gebruik van C++/WRL een veel lagere oplossing ten koste van uitgebreidere code. Niettemin, als u bekend bent met ATL-programmering (of COM in het algemeen), dan zou WRL vertrouwd aanvoelen.
In de volgende voorbeeldfunctie ziet u hoe u C++/WRL gebruikt om een specifieke bron-DLL te laden en een HINSTANCE te retourneren die kan worden gebruikt om meer resources te laden met behulp van de gebruikelijke Win32-resource-API's. In tegenstelling tot het C#-voorbeeld dat de ResourceContext expliciet initialiseert met de taal die is aangevraagd door de .NET-runtime, is deze code afhankelijk van de huidige taal van de gebruiker.
#include <roapi.h>
#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
#include <Windows.ApplicationModel.resources.core.h>
#include <Windows.Foundation.h>
#define IF_FAIL_RETURN(hr) if (FAILED((hr))) return hr;
HRESULT GetMrtResourceHandle(LPCWSTR resourceFilePath, HINSTANCE* resourceHandle)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::ApplicationModel::Resources::Core;
using namespace ABI::Windows::Foundation;
*resourceHandle = nullptr;
HRESULT hr{ S_OK };
RoInitializeWrapper roInit{ RO_INIT_SINGLETHREADED };
IF_FAIL_RETURN(roInit);
// Get Windows.ApplicationModel.Resources.Core.ResourceManager statics
ComPtr<IResourceManagerStatics> resourceManagerStatics;
IF_FAIL_RETURN(GetActivationFactory(
HStringReference(
RuntimeClass_Windows_ApplicationModel_Resources_Core_ResourceManager).Get(),
&resourceManagerStatics));
// Get .Current property
ComPtr<IResourceManager> resourceManager;
IF_FAIL_RETURN(resourceManagerStatics->get_Current(&resourceManager));
// get .MainResourceMap property
ComPtr<IResourceMap> resourceMap;
IF_FAIL_RETURN(resourceManager->get_MainResourceMap(&resourceMap));
// Call .GetValue with supplied filename
ComPtr<IResourceCandidate> resourceCandidate;
IF_FAIL_RETURN(resourceMap->GetValue(HStringReference(resourceFilePath).Get(),
&resourceCandidate));
// Get .ValueAsString property
HString resolvedResourceFilePath;
IF_FAIL_RETURN(resourceCandidate->get_ValueAsString(
resolvedResourceFilePath.GetAddressOf()));
// Finally, load the DLL and return the hInst.
*resourceHandle = LoadLibraryEx(resolvedResourceFilePath.GetRawBuffer(nullptr),
nullptr, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
return S_OK;
}
Fase 3: Resourcepacks bouwen
Nu u een 'fat pack' hebt die alle resources bevat, zijn er twee paden voor het bouwen van afzonderlijke hoofdpakketten en resourcepakketten om download- en installatiegrootten te minimaliseren:
- Neem een bestaand vetpakket en voer het uit het hulpprogramma Bundle Generator om automatisch resourcepacks te maken. Dit is de voorkeursbenadering als u een buildsysteem hebt dat al een fat pack produceert en u het wilt nabewerken om de resourcepakketten te genereren.
- Rechtstreeks de afzonderlijke resourcepakketten produceren en deze inbouwen in een bundel. Dit is de voorkeursbenadering als u meer controle hebt over uw buildsysteem en de pakketten rechtstreeks kunt bouwen.
Stap 3.1: De bundel maken
Het hulpprogramma Bundle Generator gebruiken
Als u het hulpprogramma Bundelgenerator wilt gebruiken, moet het PRI-configuratiebestand dat voor het pakket is gemaakt, handmatig worden bijgewerkt om de sectie <packaging> te verwijderen.
Als u Visual Studio gebruikt, raadpleegt u Controleer of resources op een apparaat zijn geïnstalleerd, ongeacht of een apparaat ze nodig heeft voor informatie over hoe u alle talen in het hoofdpakket kunt opnemen door de bestanden priconfig.packaging.xml en priconfig.default.xmlte maken.
Als u bestanden handmatig bewerkt, voert u de volgende stappen uit:
Maak het configuratiebestand op dezelfde manier als voorheen, waarbij u het juiste pad, de bestandsnaam en talen vervangt:
makepri createconfig /cf ..\contoso_demo.xml /dq en-US_de-DE_es-MX /pv 10.0 /oOpen het gemaakte
.xml-bestand handmatig en verwijder de hele sectie<packaging&rt;(maar houd alles intact):<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <resources targetOsVersion="10.0.0" majorVersion="1"> <!-- Packaging section has been deleted... --> <index root="\" startIndexAt="\"> <default> ... ...Bouw het
.pri-bestand en het.appx-pakket zoals voorheen, met behulp van het bijgewerkte configuratiebestand en de juiste map- en bestandsnamen (zie hierboven voor meer informatie over deze opdrachten):makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /o makeappx pack /m AppXManifest.xml /f ..\resources.map.txt /p ..\contoso_demo.appx /oNadat het pakket is gemaakt, gebruikt u de volgende opdracht om de bundel te maken met behulp van de juiste map- en bestandsnamen:
BundleGenerator.exe -Package ..\contoso_demo.appx -Destination ..\bundle -BundleName contoso_demo
U kunt nu doorgaan naar de laatste stap, ondertekening (zie hieronder).
Resourcepakketten handmatig maken
Voor het handmatig maken van resourcepakketten moet een iets andere set opdrachten worden uitgevoerd om afzonderlijke .pri- en .appx-bestanden te maken. Deze zijn allemaal vergelijkbaar met de opdrachten die hierboven worden gebruikt om fat-pakketten te maken, dus er wordt een minimale uitleg gegeven. Opmerking: bij alle opdrachten wordt ervan uitgegaan dat de huidige map de map is met het AppXManifest.xml bestand, maar alle bestanden worden in de bovenliggende map geplaatst (u kunt indien nodig een andere map gebruiken, maar u mag de projectmap niet vervuilen met een van deze bestanden). Vervang zoals altijd de bestandsnamen 'Contoso' door uw eigen bestandsnamen.
Gebruik de volgende opdracht om een configuratiebestand te maken dat alleen beschouwt als de standaardtaal voor de standaardkwalificatie; in dit geval
en-US:makepri createconfig /cf ..\contoso_demo.xml /dq en-US /pv 10.0 /oMaak een standaardbestand
.prien.map.txtvoor het hoofdpakket, plus een extra set bestanden voor elke taal in uw project, met de volgende opdracht:makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /oGebruik de volgende opdracht om het hoofdpakket te maken (dat de uitvoerbare code en standaardtaalbronnen bevat). Zoals altijd wijzigt u de naam naar wens, hoewel u het pakket in een afzonderlijke map moet plaatsen om het maken van de bundel later gemakkelijker te maken (in dit voorbeeld wordt de
..\bundledirectory gebruikt):makeappx pack /m .\AppXManifest.xml /f ..\resources.map.txt /p ..\bundle\contoso_demo.main.appx /oNadat het hoofdpakket is gemaakt, gebruikt u de volgende opdracht eenmaal voor elke extra taal (herhaal deze opdracht voor elk taaltoewijzingsbestand dat in de vorige stap is gegenereerd). Ook hier moet de uitvoer zich in een afzonderlijke map bevinden (hetzelfde als het hoofdpakket). De taal wordt opgegeven zowel in de optie
/fals in de optie/pen het gebruik van het nieuwe/rargument (wat aangeeft dat een resourcepakket gewenst is):makeappx pack /r /m .\AppXManifest.xml /f ..\resources.language-de.map.txt /p ..\bundle\contoso_demo.de.appx /oCombineer alle pakketten uit de bundelmap in één
.appxbundlebestand. Met de nieuwe/doptie geeft u de map op die moet worden gebruikt voor alle bestanden in de bundel (daarom worden de.appxbestanden in een afzonderlijke map in de vorige stap geplaatst):makeappx bundle /d ..\bundle /p ..\contoso_demo.appxbundle /o
De laatste stap voor het bouwen van het pakket is ondertekening.
Stap 3.2: de bundel ondertekenen
Nadat u het .appxbundle-bestand hebt gemaakt (via het hulpprogramma Bundelgenerator of handmatig) hebt gemaakt, hebt u één bestand met het hoofdpakket plus alle resourcepakketten. De laatste stap is het ondertekenen van het bestand, zodat Windows het installeert:
signtool sign /fd SHA256 /a /f ..\contoso_demo_key.pfx ..\contoso_demo.appxbundle
Hiermee wordt een ondertekend .appxbundle-bestand geproduceerd dat het hoofdpakket bevat plus alle taalspecifieke resourcepakketten. U kunt dubbelklikken op een pakketbestand om de app te installeren plus alle gewenste taal(en) op basis van de windows-taalvoorkeuren van de gebruiker.