Система управления ресурсами

Система управления ресурсами имеет функции, работающие во время сборки и во время выполнения. Во время построения система создает индекс всех различных вариантов ресурсов, которые упакованы с вашим приложением. Этот индекс называется индексом ресурсов пакета или PRI и также включается в пакет вашего приложения. Во время выполнения система определяет текущие параметры пользователя и компьютера, проверяет информацию в PRI и автоматически загружает ресурсы, которые лучше всего подходят для этих параметров.

Файл индекса ресурсов пакета (PRI)

Каждый пакет приложения должен содержать двоичный индекс ресурсов приложения. Этот индекс создается во время сборки и содержится в одном или нескольких файлах индекса ресурсов пакета (PRI).

  • Файл PRI содержит фактические строковые ресурсы, а также индексированный набор путей к различным файлам, содержащимся в пакете.
  • Пакет обычно включает один PRI-файл для каждого языка, который называется resources.pri.
  • Файл resources.pri, расположенный в корне каждого пакета, автоматически загружается при создании экземпляра ResourceManager.
  • Создавать и выгружать PRI-файлы можно с помощью MakePRI.exe.
  • Для разработки приложений MakePRI.exe обычно не требуется, так как он уже интегрирован в рабочий процесс компиляции Visual Studio. И Visual Studio поддерживает редактирование файлов PRI в выделенном пользовательском интерфейсе. Однако ваши локализаторы и средства, которые они используют, могут опираться на MakePRI.exe.
  • Каждый PRI-файл содержит именованный набор ресурсов — карту ресурсов. Во время загрузки PRI-файла из пакета имя карты ресурсов сопоставляется с именем идентификатора пакета.
  • PRI-файлы содержат только данные, поэтому они не используют переносимый исполняемый формат (PE). Эти файлы специально предназначены для хранения данных в формате ресурсов для Windows. Они заменяют ресурсы, которые в модели приложений Microsoft Win32 содержатся в библиотеках DLL.

Доступ к ресурсам приложения через API UWP

Базовые функции (ResourceLoader)

Самый простой способ программного доступа к ресурсам приложения — использование пространства имен Windows.ApplicationModel.Resources и класса ResourceLoader. ResourceLoader обеспечивает базовый доступ к строковым ресурсам из набора файлов ресурсов, библиотек, на которые имеются ссылки, или других пакетов.

Расширенные функции (ResourceManager)

Класс ResourceManager (в пространстве имен Windows.ApplicationModel.Resources.Core) предоставляет дополнительные сведения о ресурсах, такие как перечисление и проверка. Класс ResourceLoader такую возможность не предоставляет.

Объект NamedResource представляет собой отдельный логический ресурс с несколькими языковыми или иными квалифицированными вариантами. Он описывает логическое представление ресурса с помощью строки идентификатора ресурса, такой как Header1, или имени файла ресурсов, например logo.jpg.

Объект ResourceCandidate представляет собой одно конкретное значение ресурса и его квалификаторы, например строку Hello, world для английского языка или logo.scale-100.jpg как квалифицированный ресурс изображения, относящийся к разрешению scale-100.

Доступные приложению ресурсы хранятся в иерархических коллекциях, доступ к которым можно получить с помощью объекта ResourceMap. Класс ResourceManager предоставляет доступ к разным экземплярам ResourceMap верхнего уровня, используемым приложением, которые соответствуют разным пакетам приложения. Значение MainResourceMap соответствует карте ресурсов для текущего пакета приложения, за исключением пакетов платформ, на которые имеются ссылки. Каждая карта ResourceMap носит имя пакета, которое указано в манифесте пакета. В ResourceMap существуют поддеревья (см. ResourceMap.GetSubtree), которые содержат дополнительные объекты NamedResource. Поддеревья обычно соответствуют файлам ресурсов, которые содержат ресурс. Дополнительные сведения см. в разделах Локализация строк в манифесте пакета приложения и интерфейсе пользователя и Загрузка изображений и ресурсов, адаптированных по масштабированию, теме, высокой контрастности и другим аспектам.

Пример приведен ниже.

// using Windows.ApplicationModel.Resources.Core;
ResourceMap resourceMap =  ResourceManager.Current.MainResourceMap.GetSubtree("Resources");
ResourceContext resourceContext = ResourceContext.GetForCurrentView()
var str = resourceMap.GetValue("String1", resourceContext).ValueAsString;

Примечание. Идентификатор ресурса обрабатывается как фрагмент универсального кода ресурса (URI) с учетом семантики URI. Например, GetValue("Caption%20") обрабатывается как GetValue("Caption "). Не используйте символы "?" или "#" в идентификаторах ресурсов, так как они завершают оценку пути к ресурсу. Например, MyResource?3 трактуется как MyResource.

ResourceManager не только поддерживает доступ к строковым ресурсам приложения, но и дает возможность перечислять и проверять различные файловые ресурсы. Чтобы избежать конфликтов между файлами и другими ресурсами, которые создаются внутри файла, все индексированные пути к файлам располагаются в зарезервированном поддереве Files в ResourceMap. Например, файл \Images\logo.png соответствует имени ресурса Files/images/logo.png.

API StorageFile прозрачно обрабатывают ссылки на файлы как ресурсы и подходят для обычных сценариев использования. ResourceManager должен использоваться только для более сложных сценариев, например, если требуется переопределить текущий контекст.

ResourceContext

Ресурсы-кандидаты выбираются по конкретному ResourceContext — набору значений квалификаторов ресурсов (языка, масштаба, контрастности и т. п.). Контекст по умолчанию применяет текущую конфигурацию приложения к каждому значению квалификатора, если только он не будет переопределен. Например, такие ресурсы, как изображения, могут иметь квалификатор масштаба, который зависит от монитора и, следовательно, варьируется от одного представления приложения к другому. Поэтому каждое представление приложения имеет отдельный контекст по умолчанию. Контекст по умолчанию для данного представления можно получить при помощи ResourceContext.GetForCurrentView. При получении ресурса-кандидата нужно передать экземпляр ResourceContext, чтобы получить наиболее подходящее значение для данного представления.

Важные API