Condividi tramite


Scenario 1: Generare un file PRI da risorse stringa e file di asset

In questo scenario si useranno le API di indicizzazione delle risorse del pacchetto (PRI) per creare una nuova app per rappresentare il sistema di compilazione personalizzato. Lo scopo di questo sistema di compilazione personalizzato, tenere presente, è creare file PRI per un'app UWP di destinazione. Quindi, come parte di questa procedura dettagliata, creeremo alcuni file di risorse di esempio (contenenti stringhe e altri tipi di risorse) per rappresentare le risorse dell'app UWP di destinazione.

Nuovo progetto

Per iniziare, crea un nuovo progetto in Microsoft Visual Studio. Creare un progetto applicazione console Windows di Visual C++ e denominarlo CBSConsoleApp (per "app console del sistema di compilazione personalizzata").

Scegliere x64 dall'elenco a discesa Piattaforme soluzioni .

Intestazioni, libreria statica e dll

Le API PRI vengono dichiarate nel file di intestazione MrmResourceIndexer.h (installato in %ProgramFiles(x86)%\Windows Kits\10\Include\<WindowsTargetPlatformVersion>\um\). Aprire il file CBSConsoleApp.cpp e includere l'intestazione insieme ad altre intestazioni necessarie.

#include <string>
#include <windows.h>
#include <MrmResourceIndexer.h>

Le API vengono implementate in MrmSupport.dll, a cui si accede collegando la libreria statica MrmSupport.lib. Aprire le proprietà del progetto, fare clic su Linker>Input, modificare AdditionalDependencies e aggiungere MrmSupport.lib.

Compilare la soluzione e quindi copiarla MrmSupport.dll dalla C:\Program Files (x86)\Windows Kits\10\bin\<WindowsTargetPlatformVersion>\x64\ cartella di output di compilazione (probabilmente C:\Users\%USERNAME%\source\repos\CBSConsoleApp\x64\Debug\).

Aggiungere la funzione helper seguente a CBSConsoleApp.cpp, perché sarà necessaria.

inline void ThrowIfFailed(HRESULT hr)
{
	if (FAILED(hr))
	{
		// Set a breakpoint on this line to catch Win32 API errors.
		throw new std::exception();
	}
}

main() Nella funzione aggiungere chiamate per inizializzare e annullare l'inizializzazione di COM.

int main()
{
	::ThrowIfFailed(::CoInitializeEx(nullptr, COINIT_MULTITHREADED));
	
	// More code will go here.
	
	::CoUninitialize();
}

File di risorse appartenenti all'app UWP di destinazione

A questo punto sono necessari alcuni file di risorse di esempio (contenenti stringhe e altri tipi di risorse) per rappresentare le risorse dell'app UWP di destinazione. Questi, naturalmente, possono essere posizionati ovunque nel file system. Ma per questa procedura dettagliata sarà utile inserirli nella cartella del progetto di CBSConsoleApp in modo che tutto si trova in un'unica posizione. È sufficiente aggiungere questi file di risorse al file system; non aggiungerli al progetto CBSConsoleApp.

All'interno della stessa cartella contenente CBSConsoleApp.vcxproj, aggiungere una nuova sottocartella denominata UWPAppProjectRootFolder. All'interno di tale nuova sottocartella creare questi file di risorse di esempio.

\UWPAppProjectRootFolder\sample-image.png

Questo file può contenere qualsiasi immagine PNG.

\UWPAppProjectRootFolder\resources.resw

<?xml version="1.0"?>
<root>
	<data name="LocalizedString1">
		<value>LocalizedString1-neutral</value>
	</data>
	<data name="LocalizedString2">
		<value>LocalizedString2-neutral</value>
	</data>
	<data name="NeutralOnlyString">
		<value>NeutralOnlyString-neutral</value>
	</data>
</root>

\UWPAppProjectRootFolder\de-DE\resources.resw

<?xml version="1.0"?>
<root>
	<data name="LocalizedString2">
		<value>LocalizedString2-de-DE</value>
	</data>
</root>

\UWPAppProjectRootFolder\en-US\resources.resw

<?xml version="1.0"?>
<root>
	<data name="LocalizedString1">
		<value>LocalizedString1-en-US</value>
	</data>
	<data name="EnOnlyString">
		<value>EnOnlyString-en-US</value>
	</data>
</root>

Indicizzare le risorse e creare un file PRI

Nella funzione, prima della main() chiamata per inizializzare COM, dichiarare alcune stringhe necessarie e creare anche la cartella di output in cui verrà generato il file PRI.

std::wstring projectRootFolderUWPApp{ L"UWPAppProjectRootFolder" };
std::wstring generatedPRIsFolder{ projectRootFolderUWPApp + L"\\Generated PRIs" };
std::wstring filePathPRI{ generatedPRIsFolder + L"\\resources.pri" };
std::wstring filePathPRIDumpBasic{ generatedPRIsFolder + L"\\resources-pri-dump-basic.xml" };

::CreateDirectory(generatedPRIsFolder.c_str(), nullptr);

Subito dopo la chiamata a Initialize COM, dichiarare un handle dell'indicizzatore di risorse e quindi chiamare MrmCreateResourceIndexer per creare un indicizzatore di risorse.

MrmResourceIndexerHandle indexer;
::ThrowIfFailed(::MrmCreateResourceIndexer(
	L"OurUWPApp",
	projectRootFolderUWPApp.c_str(),
	MrmPlatformVersion::MrmPlatformVersion_Windows10_0_0_0,
	L"language-en_scale-100_contrast-standard",
	&indexer));

Ecco una spiegazione degli argomenti passati a MrmCreateResourceIndexer.

  • Il nome della famiglia di pacchetti dell'app UWP di destinazione, che verrà usato come nome della mappa delle risorse quando in seguito generiamo un file PRI da questo indicizzatore di risorse.
  • Radice del progetto dell'app UWP di destinazione. In altre parole, il percorso dei file di risorse. Questa opzione viene specificata in modo da poter specificare i percorsi relativi alla radice nelle chiamate API successive allo stesso indicizzatore di risorse.
  • Versione di Windows di destinazione.
  • Elenco dei qualificatori di risorse predefiniti.
  • Puntatore all'handle dell'indicizzatore di risorse in modo che la funzione possa impostarla.

Il passaggio successivo consiste nell'aggiungere le risorse all'indicizzatore di risorse appena creato. resources.resw è un file di risorse (con estensione resw) che contiene le stringhe neutre per l'app UWP di destinazione. Scorrere verso l'alto (in questo argomento) se si desidera visualizzarne il contenuto. de-DE\resources.resw contiene le stringhe tedesche e en-US\resources.resw le stringhe inglesi. Per aggiungere le risorse stringa all'interno di un file di risorse a un indicizzatore di risorse, chiamare MrmIndexResourceContainerAutoQualifiers. In terzo luogo, chiamiamo la funzione MrmIndexFile a un file contenente una risorsa immagine neutra all'indicizzatore di risorse.

::ThrowIfFailed(::MrmIndexResourceContainerAutoQualifiers(indexer, L"resources.resw"));
::ThrowIfFailed(::MrmIndexResourceContainerAutoQualifiers(indexer, L"de-DE\\resources.resw"));
::ThrowIfFailed(::MrmIndexResourceContainerAutoQualifiers(indexer, L"en-US\\resources.resw"));
::ThrowIfFailed(::MrmIndexFile(indexer, L"ms-resource:///Files/sample-image.png", L"sample-image.png", L""));

Nella chiamata a MrmIndexFile il valore L"ms-resource:///Files/sample-image.png" è l'URI della risorsa. Il primo segmento di percorso è "Files" ed è ciò che verrà usato come nome del sottoalbero della mappa delle risorse quando in seguito si genera un file PRI da questo indicizzatore di risorse.

Dopo aver brevemente informato l'indicizzatore di risorse sui file di risorse, è il momento di generare un file PRI su disco chiamando la funzione MrmCreateResourceFile.

::ThrowIfFailed(::MrmCreateResourceFile(indexer, MrmPackagingModeStandaloneFile, MrmPackagingOptionsNone, generatedPRIsFolder.c_str()));

A questo punto, un file PRI denominato resources.pri è stato creato all'interno di una cartella denominata Generated PRIs. Ora che l'indicizzatore di risorse è stato completato, viene chiamato MrmDestroyIndexerAndMessages per distruggere l'handle e rilasciare tutte le risorse del computer allocate.

::ThrowIfFailed(::MrmDestroyIndexerAndMessages(indexer));

Poiché un file PRI è binario, sarà più semplice visualizzare ciò che è stato appena generato se si esegue il dump del file PRI binario nell'equivalente XML. Una chiamata a MrmDumpPriFile lo fa.

::ThrowIfFailed(::MrmDumpPriFile(filePathPRI.c_str(), nullptr, MrmDumpType::MrmDumpType_Basic, filePathPRIDumpBasic.c_str()));

Ecco una spiegazione degli argomenti passati a MrmDumpPriFile.

  • Il percorso del file PRI da scaricare. Non si usa l'indicizzatore di risorse in questa chiamata (è stato eliminato definitivamente), quindi è necessario specificare un percorso di file completo.
  • Nessun file di schema. Verrà illustrato cosa sarà uno schema più avanti nell'argomento.
  • Solo le informazioni di base.
  • Percorso completo di un file XML da creare.

Questo è ciò che il file PRI, sottoposto a dump in XML, contiene.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PriInfo>
	<ResourceMap name="OurUWPApp" version="1.0" primary="true">
		<Qualifiers>
			<Language>en-US,de-DE</Language>
		</Qualifiers>
		<ResourceMapSubtree name="Files">
			<NamedResource name="sample-image.png" uri="ms-resource://OurUWPApp/Files/sample-image.png">
				<Candidate type="Path">
					<Value>sample-image.png</Value>
				</Candidate>
			</NamedResource>
		</ResourceMapSubtree>
		<ResourceMapSubtree name="resources">
			<NamedResource name="EnOnlyString" uri="ms-resource://OurUWPApp/resources/EnOnlyString">
				<Candidate qualifiers="Language-en-US" isDefault="true" type="String">
					<Value>EnOnlyString-en-US</Value>
				</Candidate>
			</NamedResource>
			<NamedResource name="LocalizedString1" uri="ms-resource://OurUWPApp/resources/LocalizedString1">
				<Candidate qualifiers="Language-en-US" isDefault="true" type="String">
					<Value>LocalizedString1-en-US</Value>
				</Candidate>
				<Candidate type="String">
					<Value>LocalizedString1-neutral</Value>
				</Candidate>
			</NamedResource>
			<NamedResource name="LocalizedString2" uri="ms-resource://OurUWPApp/resources/LocalizedString2">
				<Candidate qualifiers="Language-de-DE" type="String">
					<Value>LocalizedString2-de-DE</Value>
				</Candidate>
				<Candidate type="String">
					<Value>LocalizedString2-neutral</Value>
				</Candidate>
			</NamedResource>
			<NamedResource name="NeutralOnlyString" uri="ms-resource://OurUWPApp/resources/NeutralOnlyString">
				<Candidate type="String">
					<Value>NeutralOnlyString-neutral</Value>
				</Candidate>
			</NamedResource>
		</ResourceMapSubtree>
	</ResourceMap>
</PriInfo>

Le informazioni iniziano con una mappa delle risorse denominata con il nome della famiglia di pacchetti dell'app UWP di destinazione. Racchiuso dalla mappa delle risorse sono due sottoalberi della mappa delle risorse: uno per le risorse file indicizzate e un altro per le risorse stringa. Si noti che il nome della famiglia di pacchetti è stato inserito in tutti gli URI della risorsa.

La prima risorsa stringa è EnOnlyString da en-US\resources.reswe ha un solo candidato (che corrisponde al qualificatore language-en-US ). Successivamente viene localizedString1 da resources.resw e en-US\resources.resw. Di conseguenza, ha due candidati: una lingua corrispondente en-US e un candidato neutro di fallback che corrisponde a qualsiasi contesto. Analogamente, LocalizedString2 ha due candidati: language-de-DE e neutral. E, infine, NeutralOnlyString esiste solo in forma neutra. Ho dato questo nome per rendere chiaro che non è destinato a essere localizzato.

Riepilogo

In questo scenario è stato illustrato come usare le API pri (Package Resource Indexing) per creare un indicizzatore di risorse. Sono state aggiunte risorse stringa e file di asset all'indicizzatore di risorse. È stato quindi usato l'indicizzatore di risorse per generare un file PRI binario. E infine abbiamo scaricato il file PRI binario sotto forma di XML in modo da poter confermare che contiene le informazioni previste.

API importanti