Resource Management System
The Resource Management System runs when you build your app. It creates a file that is packaged with the app and helps to resolve resources at run time.
Every application package should contain a binary index of the resources in the app. This file is created at build time and is referred to as a Package Resource Index (PRI) file.
- The PRI file is packaged with the rest of the app and helps to resolve resources at run time.
- The PRI contains actual string resources, and an indexed set of file paths that refer to the files in the package.
- Packages typically contain a single PRI file named resources.pri.
- The resources.pri file from the root of each package is automatically loaded when the ResourceManager is instantiated.
- PRI files can be created and dumped with MakePRI.exe.
- When a PRI file is loaded, the internal resource map names, which are generated during the build of the PRI, are verified against the set of package identity names for the app.
- PRI files are data-only and are not of the PE format. They are specifically designed to be data-only as the resource format for Windows. They replace resources contained within DLLs in the Win32 app model.
A NamedResource is an individual logical resource with multiple language or other qualified variants. It describes the logical view of the asset or resource, with a name such as
A ResourceCandidate is a single concrete resource value and its qualifiers, such as the string "Hello World" for English or "logo.scale-100.jpg" for scale 100 devices.
Resources available to an app are stored hierarchically, and the ResourceManager provides access to the various top-level ResourceMaps. The top-level ResourceMaps for Windows Store apps correspond to the various packages for the app. The mainResourceMap corresponds to the current application package, not to its referenced framework packages. Each ResourceMap is named after the package name that is specified in the package's manifest. Within a ResourceMap are ResourceMap Subtrees (see ResourceMap.GetSubtree), which further contain NamedResources. The subtrees typically correspond to the resource file (see How to load string resources) that contains the resource.
var resMap = Windows.ApplicationModel.Resources.Core.ResourceManager.current.mainResourceMap; var str = resMap.getValue("Resources/String1").valueAsString;
Note Resource identifier arguments are treated as Uniform Resource Identifier (URI) fragments, subject to URI semantics. For example, getValue("Caption%20") is treated as getValue("Caption "). Do not use "?" or "#" in resource identifiers, as they terminate the named resource path. For example, "Foo?3" is treated as "Foo".
The ResourceManager not only supports access to an app's string resources, but it maintains the ability to enumerate and inspect the various file resources as well. In order to avoid collisions between files and other resources that originate from within a file, indexed file paths all reside within a reserved "Files" ResourceMap Subtree. For example, the file "images/logo.png" corresponds to the resource name "Files/images/Logo.png".
The StorageFile APIs transparently handle references to files as resources and are appropriate for typical usage scenarios. The ResourceManager should only be used for advanced scenarios, such as overridden context or enumeration of possible values.
Resource candidates are chosen based on a particular context. If a context is not passed into a method that is looking up resources, ResourceManager.DefaultContext is used. The default context uses the app's current configuration for each qualifier value, unless overridden.
If a candidate has any qualifiers that don't match (for example, the user doesn't speak a given language), that resource candidate is thrown out of consideration. The definition of "match" is dependent upon the qualifier. For example, scale-100 matches scale-140 to some degree, but "en-US" does not match "fr-FR".
The remaining candidates are then sorted. The comparison is done by looking at the highest-priority context qualifier: language, then contrast, then scale, and so on. The one that best matches that context qualifier is chosen. For example, "en-US" matches the "en-US" user preference better than "en-GB" does.
Neutral candidates, which are the candidates not marked with a qualifier, always match, but they are chosen after any other matched qualifiers and their candidate. For example, if we have resources for "en-US", "en", "fr", and a neutral resource, then for a user that wants "en-GB" the candidates match in the following order: "en, en-US, neutral, fr". In this case, "fr" does not match at all but the other candidates match to some degree.
If there is a tie based on language, then contrast is inspected as the next-highest priority context qualifier. This process continues, until a best match is found. Any non-matching qualifier removes a candidate from consideration as a primary match.
If all candidates are removed from consideration due to qualifiers that don't match the context, the resource loader goes through a second pass looking for a default candidate to display. Default candidates are determined during creation of the PRI file (see Compiling resources (MakePRI.exe) for details). If a candidate has any qualifiers that don't match and aren't a default, that resource candidate is thrown permanently out of consideration.
For all the resource candidates still in consideration, we look at highest-priority context qualifier value and choose the one that has the best match or best default score. Any actual match is considered better than a default score.
If there is a tie, the next-highest priority context qualifier value is inspected and the process continues, until a best match is found.
For examples, see Examples of how resources are chosen.
MakePRI.exe is a command line tool used for creating and dumping PRI files. It is integrated as part of MSBuild within Microsoft Visual Studio, but can be useful for developers to create packages by hand or by custom build systems.
MakePRI.exe has a set of command options: createconfig, new, versioned, resourcepack, and dump. For details of their use, see MakePRI.exe command options.
The PRI XML configuration file dictates how and what resources are indexed. The schema of the configuration XML is described in MakePRI.exe configuration.
MakePRI.exe typically uses the new, versioned, or resourcepack options. In those cases it indexes source files to generate its index of resources. MakePRI.exe uses various individual indexers to read different resource files or containers for resources. The simplest indexer is the folder indexer, which indexes the contents of a folder, such as .jpg or .png images.
The format-specific indexers are identified by <index-config> elements within an <index> element. The type attribute identifies the format-specific indexer that is used.
Resource containers encountered during indexing usually get their contents indexed rather than being added to the index themselves. For example, .resjson files that the folder indexer finds may be further indexed by a .resjson indexer, in which case the .resjson file itself does not appear in the index. Typically, qualifiers found on a containing entity, such as a folder, are applied to all resources within it, such as the strings in a resource file.
See Format-specific indexers for the descriptions and schemas of the following indexer types.
The folder indexer is identified by a type attribute of FOLDER. It indexes the contents of a folder, and determines resource qualifiers from the folder and file names. See the Folder section of the Format-specific indexers topic.
The ResJSON indexer is identified by a type attribute of RESJSON. It indexes the contents of a .resjson file, which is a string resource file. See the ResJSON section of the Format-specific indexers topic.
The PRI indexer is identified by a type attribute of PRI. It indexes the contents of a PRI file. It is typically used to index a resource contained in another assembly, DLL, SDK, or class library.
All resource names, qualifiers and values contained in the PRI file are directly maintained in the new PRI file. The top level resource map however is not maintained in the final PRI. Resource Maps are merged.
The PRIInfo indexer is identified by a type attribute of PRIINFO. It indexes the contents of a detailed dump file. The dump file is produced by using the dump command from MakePri.exe, with the detailed dump type option. See the PRIINFO section of the Format-specific indexers topic.
Resources found for language(s) '<language(s)>' but no resources found for default language(s): '<language(s)>'. Change the default language or qualify resources with the default language.
is displayed when MakePRI.exe or MSBuild discovers files or resources that appear to be marked with language qualifiers that have no resources for those languages. The process for marking files is described in How to name resources using qualifiers. A file or folder may have a language name in it, but no resources are discovered that are qualified for the exact default language. For example, if a project has a file named "de/logo.png" but does not have any files that are marked with the default language, "en-US", this warning will appear. In order to remove this warning, either file(s) or resource(s) should be qualified with the default language, or the default language should be changed. You can change the default language in Windows Store app projects by opening package.appxmanifest in Visual Studio and editing "Default language" in the Application UI tab.
No default or neutral resource given for '<resource identifier>'. The application may throw an exception for certain user configurations when retrieving the resources.
is displayed when MakePRI.exe or MSBuild discovers files or resources that appear to be marked with language qualifiers for which the resources are unclear. There are qualifiers, but there is no guarantee that a particular resource candidate can be returned for that resource identifier at run time. If no resource candidate for a particular language, homeregion, or other qualifier can be found that is a default or will always match the context of a user, this warning will be displayed. At run time, for particular user configurations such as a user's language preferences (Control Panel > Clock, Language, and Region > Language) or home location (Control Panel > Clock, Language, and Region > Change location), the APIs used to retrieve the resource may throw an unexpected exception. In order to remove this warning, default resources should be provided, such as a resource in the project's default language or global home region (homeregion-001).
Build systems should use the MakePRI.exe new, versioned, or resourcepack commands, depending on the type of project being built. Build systems that create a fresh PRI file should use the "new" command. Build systems that must ensure compatibility of internal offsets through iterations can use the "versioned" command. Build systems that must create a PRI file that contains additional variants of resources, with validation to ensure that no new resources are added for that variant, should use the "resourcepack" command.
Build systems that must be more explicit with their resources can use the ResFiles indexer instead of indexing a folder. Build systems can also use multiple index passes with different format-specific indexers, to generate a single PRI file.
Build systems can also use the PRI format-specific indexer to add pre-built PRI files into the PRI for the package from other components, such as class libraries, assemblies, SDKs, and DLLs.
When PRI files are built for other components, class libraries, assemblies, DLLs, and SDKs, the initialPath configuration should be used to ensure component resources have their own sub resource maps that don't conflict with the app they're included in.
- Other topics
- Examples of how resources are chosen
- MakePRI.exe command options
- MakePRI.exe configuration
- Format-specific indexers
- How to load string resources
- How to name resources using qualifiers
Build date: 11/13/2012