Ресурси, подібні зображень і строковим таблиць, можуть поміщатися в файли ресурсів або підлеглі збірки. Ці ресурси можуть бути дуже корисні при локалізації додатків, і в .NET пропонується вбудована підтримка для пошуку локалізованих ресурсів.
Перш ніж подивитися, як застосовувати ресурси для локалізації додатків, спочатку ознайомимося з методами створення і читання ресурсів без врахування мовних аспектів.
Створення файлів ресурсів
У файлах ресурсів можуть зберігатися елементи, подібні зображень і таблиць рядків. Як ресурсного файлу може бути звичайний текстовий файл або файл з розширенням .resX, в якому використовується XML. У цій статті спочатку розглядається варіант простого текстового файлу.
Ресурс, що включає в себе таблицю рядків, може створюватися в звичайному текстовому файлі. У цьому файлі просто проводиться призначення рядків ключам. Під ключем розуміється ім'я, яке може використовуватися в програмі для отримання відповідного значення. У ключах і значеннях допускається використовувати прогалини.
Нижче показаний приклад створення простої таблиці рядків:
утиліта Resgen.exe
Для створення з ***. Txt файлу ресурсів можна скористатися спеціальною утилітою генерації файлів ресурсів Resgen.exe. Наприклад, введення наступної команди:
приведе до створення файлу MyResources.resources. Згенерований цією програмою файл ресурсів далі можна або додати в збірку як зовнішній файл, або вставити в збірку DLL або ЕХЕ. Утиліта Resgen також підтримує можливість створення файлів ресурсів в форматі XML з розширенням .resX. Застосовується вона дуже просто:
Виконання цієї команди приведе до створення XML-файла ресурсів на ім'я MyResources.resX.
Утиліта Resgen підтримує строго типізовані ресурси. Строго типізований ресурс представляється у вигляді класу, який отримує доступ до ресурсів. Для створення такого класу в утиліті Resgen передбачена опція / str:
Після опції / str повинен бути вказана мова, простір імен, ім'я класу і ім'я файлу вихідного коду, причому саме в такому порядку.
Можливість додавання зображень утиліта Resgen не підтримує. Серед прикладів .NET Framework SDK є і приклад ResXGen з навчальними посібниками. У ResXGen можна посилатися на зображення у файлі .resX. Додавати зображення можна також програмно із застосуванням класів ResourceWriter або ResXResourceWriter, як буде показано далі.
клас ResourceWriter
Замість використання для створення файлів ресурсів утиліти Resgen можна написати спеціальну, що дозволяє це робити програму. Клас ResourceWriter з простору імен System.Resources служить для створення бінарних файлів ресурсів, а клас ResXResourceWriter - для створення файлів ресурсів на базі XML. Обидва ці класу підтримують можливість додавання зображень і будь-яких інших Серіалізуемое об'єктів. У разі застосування класу ResXResourceWriter потрібно послатися на збірку System.Windows.Forms.
У наступному прикладі коду демонструється створення об'єкта ResXResourceWriter по імені rw в файлі Demo.resx. Після створення екземпляра за допомогою методу AddResource () класу ResXResourceWriter можна приступати до додавання набору ресурсів загальним обсягом до 2 Гбайт. Перший аргумент в AddResource () дозволяє вказувати ім'я ресурсу, а другий - значення. Ресурс зображення можна додавати за рахунок застосування примірника класу Image. Щоб можна було використовувати клас Image, необхідно послатися на збірку System.Drawing, а також додати директиву using для відкриття простору імен System.Drawing.
Тут об'єкт Image створюється за рахунок відкриття файлу logo.gif, тому потрібно або скопіювати цей файл зображення в каталог виконуваної програми, або вказати повний шлях до нього в аргументі методу ImageToFile (). Оператор using вказує, що ресурс зображення повинен автоматично знищуватися в кінці блоку using.
Далі в об'єкт ResXResourceWriter додаються прості строкові ресурси. В кінці метод Close () класу ResXResourceWriter автоматично викликає ResXResourceWriter.Generate () для здійснення запису ресурсів в файл Demo.resx:
Запуск цієї невеликої програми призведе до створення файлу ресурсів Demo.resx із зображенням logo.gif всередині.
Використання файлів ресурсів
Додайте в цей проект створений раніше файл ресурсів Demo.resx, відкривши в вікні Solution Explorer контекстне меню і вибравши в ньому пункт Add -> Add Existing Item (Додати -> Додати існуючий елемент). За замовчуванням для властивості Build Action (Дія при компонуванні) цього ресурсу буде встановлено значення Embedded Resource (Вбудований ресурс), яке вказує, що цей ресурс повинен вбудовуватися в вихідну збірку.
Далі в параметрах проекту (за рахунок вибору Application -> Assembly information (Додаток -> Інформація про збірку)) слід встановити в якості значення параметра Neutral Language (Нейтральний мова) основна мова:
Зміна значення цього параметра призведе до додавання в файл assemblyinfо.cs атрибута [NeutralResourceLanguageAttribute]. як показано нижче:
Установка значення для даного атрибута поліпшить продуктивність ResourceManager, оскільки дозволить йому швидше відшукувати ресурси для en-US, а також використовувати їх в якості варіанту за замовчуванням. У цьому атрибуті можна також вказати місце розміщення використовуваного за замовчуванням ресурсу за рахунок застосування другого параметра в конструкторі. За допомогою перерахування UltimateResourceFallbackLocation можна вказати, що він повинен розміщуватися в головній збірці (значення MainAssembly) або ж в підпорядкованої (значення Satellite).
Для отримання доступу до вбудованого ресурсу використовується клас ResourceManager, який знаходиться в просторі імен System.Resources. Конструктору цього класу в якості аргументу можна передати ім'я збірки, в якій містяться ресурси.
У розглянутому прикладі ресурси вбудовані в виконувану збірку, тому в другому аргументі конструктору повинен бути переданий результат виконання методу Assembly.GetExecutingAssembly (). У першому аргументі передається кореневе ім'я ресурсів, що складається з назви простору імен та імені файлу ресурсів, але без розширення resources. Як було показано раніше, це ім'я можна відобразити за допомогою утиліти ildasm і просто видалити з нього розширення resources. Ім'я можна також отримати і програмно із застосуванням методу GetManifestResourceNames () класу System.Reflection.Assembly:
Простір імен System.Resources
Давайте коротко пройдемося по всіх класах, які містяться в просторі імен System.Resources і дозволяють працювати з ресурсами.
Може використовуватися для отримання ресурсів, що відносяться до поточної культурі, з збірок або файлів ресурсів. За допомогою ResourceManager можна отримувати відразу цілий набір ресурсів для певної культури в вигляді примірника ResourceSet.
Дозволяє представляти набір ресурсів для певної культури. При створенні екземпляр ResourceSet він виробляє перерахування по класу, реалізуючи інтерфейс IResourceReader, і зберігає всі ресурси в HashTable.
Використовується в ResourceSet для перерахування ресурсів. Клас ResourceReader реалізує цей інтерфейс.
Застосовується для створення файлу ресурсів і реалізує інтерфейс IResourceWriter.
Класи ResXResourceSet, ResXResourceReader і ResXResourceWriter
Схожі на класи ResourceSet, ResourceReader і ResourceWriter, але служать для створіння не бінарного файлу ресурсів, а не XML-файла .resx. Замість того щоб вбудовувати ресурс в XML-файл, вони дозволяють додавати на нього посилання з допомогою ResXFileRef.
Простір імен System.Resources.Tools
Містить клас StronglyTypedResourceBuilder, який можна використовувати для створення класу з ресурсу.