Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Это важно
Вызов методов из этого класса с ненадежными данными является угрозой безопасности. Вызовите методы из этого класса только с доверенными данными. Дополнительные сведения см. в разделе Проверка всех входных данных.
Класс ResourceManager извлекает ресурсы из двоичного файла РЕСУРСОВ, внедренного в сборку или из автономного файла ресурсов. Если приложение было локализовано и локализовано в вспомогательных сборках, он ищет ресурсы, зависящие от языка и региональных параметров, предоставляет резервную передачу ресурсов, если локализованный ресурс не существует, и поддерживает сериализацию ресурсов.
Настольные приложения
Для классических приложений класс ResourceManager извлекает ресурсы из двоичных файлов ресурсов (.resources). Как правило, компилятор языка или компоновщик сборок (AL.exe) внедряет эти файлы ресурсов в сборку. Можно также использовать объект ResourceManager для извлечения ресурсов непосредственно из файла ресурсов, который не внедрен в сборку, путем вызова метода CreateFileBasedResourceManager.
Осторожность
Использование автономных файлов ресурсов в приложении ASP.NET прерывает развертывание XCOPY, так как ресурсы остаются заблокированными, пока они не будут явно освобождены методом ReleaseAllResources. Если вы хотите развернуть ресурсы вместе с приложениями ASP.NET, необходимо скомпилировать файлы ресурсов в сателлитные сборки.
В приложении на основе ресурсов один файл .resources содержит ресурсы культуры по умолчанию, которые используются, если ресурсы для конкретной культуры не найдены. Например, если язык и региональные параметры по умолчанию приложения — английский (en), ресурсы английского языка используются, когда локализованные ресурсы не могут быть найдены для определенного языка и региональных параметров, таких как английский (США) (en-US) или французский (Франция) (fr-FR). Как правило, ресурсы для культуры по умолчанию внедрены в основную сборку приложения, а ресурсы для других локализованных культур внедрены в сателлитные сборки. Сателлитные сборки содержат только ресурсы. Они имеют то же имя корневого файла, что и основная сборка и расширение .resources.dll. Для приложений, сборки которых не зарегистрированы в глобальном кэше сборок, спутниковые сборки хранятся в подкаталоге приложения, имя которого соответствует культуре сборки.
Создание ресурсов
При разработке приложения на основе ресурсов вы храните сведения о ресурсах в текстовых файлах (файлы с расширением .txt или RESTEXT) или XML-файлы (файлы с расширением RESX). Затем вы компилируете текстовые или XML-файлы с помощью генератора файлов ресурсов (Resgen.exe) для создания двоичного файла ресурсов. Затем можно внедрить результирующий файл ресурсов в исполняемый файл или библиотеку с помощью параметра компилятора, например /resources
для компиляторов C# и Visual Basic, или внедрить его в спутниковую сборку с помощью компоновщика сборок (AI.exe). Если в проект Visual Studio включен RESX-файл, Visual Studio обрабатывает компиляцию и внедрение стандартных и локализованных ресурсов автоматически в процессе сборки.
В идеале следует создавать ресурсы для каждого языка, который поддерживает приложение, или по крайней мере для понятного подмножества каждого языка. Имена файлов двоичных ресурсов соответствуют соглашению об именовании basename.cultureName.resources, где basename — это имя приложения или имя класса в зависимости от нужного уровня детализации. Свойство CultureInfo.Name используется для определения cultureName. Ресурс для культуры по умолчанию приложения должен называться basename.resources.
Например, предположим, что сборка содержит несколько ресурсов в файле ресурсов с базовым именем MyResources. Эти файлы ресурсов должны иметь такие имена, как MyResources.ja-JP.resources для японской культуры, MyResources.de.resources для немецкой культуры, MyResources.zh-CHS.resources для культуры упрощенного китайского языка и MyResources.fr-BE.resources для французской (Бельгия) культуры. Файл ресурсов по умолчанию должен называться MyResources.resources. Файлы ресурсов, зависящие от языка и региональных параметров, обычно упаковываются в вспомогательные сборки для каждого языка и региональных параметров. Файл ресурсов по умолчанию должен быть внедрен в основную сборку приложения.
Обратите внимание, что компоновщик сборок позволяет ресурсам помечаться как закрытые, но их всегда следует пометить как общедоступные, чтобы они могли получить доступ к другим сборкам. (Так как в сателлитной сборке нет кода, ресурсы, помеченные как частные, недоступны вашему приложению ни одним способом.)
Для получения дополнительной информации о создании, упаковке и развертывании ресурсов см. статьи: «Создание файлов ресурсов», «Создание спутниковых сборок»и «Упаковка и развертывание ресурсов».
Инстанцировать объект ResourceManager
Вы создаете экземпляр объекта ResourceManager, который извлекает ресурсы из внедренного файла ресурсов, вызывая одну из перегрузок конструктора класса. Это тесно связывает объект ResourceManager с определенным файлом ресурсов и любыми связанными локализованными файлами ресурсов в вспомогательных сборках.
Два наиболее часто называемых конструктора:
ResourceManager(String, Assembly) ищет ресурсы на основе двух частей сведений, которые вы предоставляете: базовое имя файла ресурсов и сборка, в которой находится файл ресурсов по умолчанию. Базовое имя включает пространство имен и корневое имя файла .resources без учета его культуры и расширения. Обратите внимание, что файлы ресурсов, скомпилированные из командной строки, обычно не включают имя пространства имен, тогда как файлы ресурсов, созданные в среде Visual Studio, его включают. Например, если файл ресурсов называется MyCompany.StringResources.resources, а конструктор ResourceManager вызывается из статического метода с именем
Example.Main
, следующий код создает экземпляр объекта ResourceManager, который может получить ресурсы из файла .resources:ResourceManager rm = new ResourceManager("MyCompany.StringResources", typeof(Example).Assembly);
Dim rm As New ResourceManager("MyCompany.StringResources", GetType(Example2).Assembly)
ResourceManager(Type) ищет ресурсы в сателлитных сборках с использованием информации из объекта типа. Полное имя типа соответствует базовому имени файла .resources без расширения имени файла. В классических приложениях, созданных с помощью конструктора ресурсов Visual Studio, Visual Studio создает класс оболочки, полный имя которого совпадает с корневым именем файла .resources. Например, если файл ресурсов называется MyCompany.StringResources.resources и существует класс оболочки с именем
MyCompany.StringResources
, следующий код создает экземпляр объекта ResourceManager, который может получить ресурсы из файла ресурсов:ResourceManager rm = new ResourceManager(typeof(MyCompany.StringResources));
Dim rm As New ResourceManager(GetType(MyCompany.StringResources))
Если не удается найти соответствующие ресурсы, вызов конструктора создает допустимый объект ResourceManager. Однако попытка получить ресурс вызывает исключение MissingManifestResourceException. Сведения о работе с исключением см. в разделе Handle MissingManifestResourceException и MissingSatelliteAssemblyException, подразделе ниже в этой статье.
В следующем примере показано, как создать экземпляр объекта ResourceManager. Он содержит исходный код для исполняемого файла с именем ShowTime.exe. Он также включает следующий текстовый файл с именем Strings.txt, который содержит один строковый ресурс, TimeHeader
:
TimeHeader=The current time is
Пакетный файл можно использовать для создания файла ресурсов и внедрения его в исполняемый файл. Ниже приведен пакетный файл для создания исполняемого файла с помощью компилятора C#:
resgen strings.txt
csc ShowTime.cs /resource:strings.resources
Для компилятора Visual Basic можно использовать следующий пакетный файл:
resgen strings.txt
vbc ShowTime.vb /resource:strings.resources
using System;
using System.Resources;
public class ShowTimeEx
{
public static void Main()
{
ResourceManager rm = new ResourceManager("Strings",
typeof(Example).Assembly);
string timeString = rm.GetString("TimeHeader");
Console.WriteLine($"{timeString} {DateTime.Now:T}");
}
}
// The example displays output like the following:
// The current time is 2:03:14 PM
Imports System.Resources
Module Example6
Public Sub Main()
Dim rm As New ResourceManager("Strings", GetType(Example6).Assembly)
Dim timeString As String = rm.GetString("TimeHeader")
Console.WriteLine("{0} {1:T}", timeString, Date.Now)
End Sub
End Module
' The example displays output similar to the following:
' The current time is 2:03:14 PM
Ресурсы ResourceManager и культуроспецифические ресурсы
Локализованное приложение требует развертывания ресурсов, как описано в статье упаковка и развертывание ресурсов. Если сборки настроены правильно, диспетчер ресурсов определяет, какие ресурсы необходимо получить на основе свойства Thread.CurrentUICulture текущего потока. (Это свойство также возвращает региональные настройки пользовательского интерфейса текущего потока.) Например, если приложение компилируется с ресурсами английского языка по умолчанию в основной сборке и с ресурсами французского и русского языка в двух сателлитных сборках, а свойство Thread.CurrentUICulture имеет значение fr-FR, диспетчер ресурсов извлекает французские ресурсы.
Свойство CurrentUICulture можно задать явно или неявно. Способ настройки определяет, как объект ResourceManager получает ресурсы на основе культурных особенностей.
Если явно задать свойство Thread.CurrentUICulture для определённой культуры, диспетчер ресурсов всегда получает ресурсы для этой культуры, независимо от браузера пользователя или языка операционной системы. Рассмотрим приложение, скомпилированное по умолчанию с ресурсами английского языка и тремя вспомогательными сборками, содержащими ресурсы для английского (США), французского (Франция) и российского (Россия). Если для свойства CurrentUICulture задано значение fr-FR, объект ResourceManager всегда получает ресурсы для французского языка (Франция), даже если язык операционной системы пользователя не французский. Убедитесь, что это нужное поведение перед явной настройкой свойства.
В приложениях ASP.NET необходимо явно задать свойство Thread.CurrentUICulture, так как маловероятно, что параметр на сервере будет соответствовать входящим клиентским запросам. Приложение ASP.NET может явно задать свойство Thread.CurrentUICulture в соответствии с предпочитаемым языком браузера пользователя.
Установка свойства Thread.CurrentUICulture явно задает язык пользовательского интерфейса и региональные параметры для данного потока. Он не влияет на текущую культуру пользовательского интерфейса других потоков в приложении.
Вы можете установить культуру пользовательского интерфейса всех потоков в домене приложения, назначив объект CultureInfo, представляющий эту культуру, статическому свойству CultureInfo.DefaultThreadCurrentUICulture.
Если вы явно не задаете текущий язык и региональные параметры пользовательского интерфейса и не определяете язык и региональные параметры по умолчанию для текущего домена приложения, свойство CultureInfo.CurrentUICulture устанавливается неявно функцией Windows
GetUserDefaultUILanguage
. Эта функция предоставляется многоязычным пользовательским интерфейсом (MUI), который позволяет пользователю задать язык по умолчанию. Если язык пользовательского интерфейса не задан пользователем, он по умолчанию используется для установленного системой языка, который является языком ресурсов операционной системы.
Следующий простой пример Hello world явно задает текущие региональные настройки пользовательского интерфейса. Он содержит ресурсы для трех культур: английский (США) или en-US, французский (Франция) или fr-FR, а также русский (Россия) или ru-RU. Ресурсы en-US содержатся в текстовом файле с именем Greetings.txt:
HelloString=Hello world!
Ресурсы fr-FR содержатся в текстовом файле с именем Greetings.fr-FR.txt:
HelloString=Salut tout le monde!
Ресурсы ru-RU содержатся в текстовом файле с именем Greetings.ru-RU.txt:
HelloString=Всем привет!
Ниже приведен исходный код для примера (Example.vb для версии Visual Basic или Example.cs для версии C#):
using System;
using System.Globalization;
using System.Resources;
using System.Threading;
public class Example
{
public static void Main()
{
// Create array of supported cultures
string[] cultures = { "en-CA", "en-US", "fr-FR", "ru-RU" };
Random rnd = new Random();
int cultureNdx = rnd.Next(0, cultures.Length);
CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
ResourceManager rm = new ResourceManager("Greetings", typeof(Example).Assembly);
try
{
CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
Thread.CurrentThread.CurrentCulture = newCulture;
Thread.CurrentThread.CurrentUICulture = newCulture;
string greeting = String.Format("The current culture is {0}.\n{1}",
Thread.CurrentThread.CurrentUICulture.Name,
rm.GetString("HelloString"));
Console.WriteLine(greeting);
}
catch (CultureNotFoundException e)
{
Console.WriteLine($"Unable to instantiate culture {e.InvalidCultureName}");
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalCulture;
}
}
}
// The example displays output like the following:
// The current culture is ru-RU.
// Всем привет!
Imports System.Globalization
Imports System.Resources
Imports System.Threading
Module Example
Sub Main()
' Create array of supported cultures
Dim cultures() As String = {"en-CA", "en-US", "fr-FR", "ru-RU" }
Dim rnd As New Random()
Dim cultureNdx As Integer = rnd.Next(0, cultures.Length)
Dim originalCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Dim rm As New ResourceManager("Greetings", GetType(Example).Assembly)
Try
Dim newCulture As New CultureInfo(cultures(cultureNdx))
Thread.CurrentThread.CurrentCulture = newCulture
Thread.CurrentThread.CurrentUICulture = newCulture
Dim greeting As String = String.Format("The current culture is {0}.{1}{2}",
Thread.CurrentThread.CurrentUICulture.Name,
vbCrLf, rm.GetString("HelloString"))
Console.WriteLine(greeting)
Catch e As CultureNotFoundException
Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName)
Finally
Thread.CurrentThread.CurrentCulture = originalCulture
Thread.CurrentThread.CurrentUICulture = originalCulture
End Try
End Sub
End Module
' The example displays output like the following:
' The current culture is ru-RU.
' Всем привет!
Чтобы скомпилировать этот пример, создайте пакетный файл (.bat), содержащий следующие команды, и запустите его из командной строки. Если вы используете C#, укажите csc
вместо vbc
и Example.cs
вместо Example.vb
.
resgen Greetings.txt
vbc Example.vb /resource:Greetings.resources
resgen Greetings.fr-FR.txt
Md fr-FR
al /embed:Greetings.fr-FR.resources /culture:fr-FR /out:fr-FR\Example.resources.dll
resgen Greetings.ru-RU.txt
Md ru-RU
al /embed:Greetings.ru-RU.resources /culture:ru-RU /out:ru-RU\Example.resources.dll
Извлечение ресурсов
Вы вызываете методы GetObject(String) и GetString(String) для доступа к определенному ресурсу. Можно также вызвать метод GetStream(String) для извлечения нестроковых ресурсов в виде массива байтов. По умолчанию в приложении с локализованными ресурсами эти методы возвращают ресурс для культуры, определённой текущей культурой потока, который сделал вызов. Дополнительную информацию о том, как определяется текущий язык интерфейса пользователя потока, см. в предыдущем разделе, посвященном ResourceManager и региональным ресурсам . Если диспетчер ресурсов не может найти ресурс для языка и региональных параметров пользовательского интерфейса текущего потока, он использует резервный процесс для получения указанного ресурса. Если диспетчер ресурсов не может найти локализованные ресурсы, он использует ресурсы культуры по умолчанию. Дополнительные сведения о правилах резервного копирования ресурсов см. в разделе "Резервный процесс ресурсов" статьи Упаковка и развертывание ресурсов.
Примечание.
Если файл ресурсов, указанный в конструкторе классов ResourceManager, не найден, попытка получить ресурс вызывает исключение MissingManifestResourceException или MissingSatelliteAssemblyException. Сведения о работе с исключением см. в разделе Handle MissingManifestResourceException и MissingSatelliteAssemblyException, подразделе ниже в этой статье.
В следующем примере используется метод GetString для получения культуроспецифических ресурсов. Он состоит из ресурсов, скомпилированных из .txt файлов для английского языка (en), французского (Франция) (fr-FR) и российских (Россия) (ru-RU) культур. Пример изменяет текущую культуру и текущие культурные параметры пользовательского интерфейса на английский (США), французский (Франция), русский (Россия) и шведский (Швеция). Затем он вызывает метод GetString для получения локализованной строки, которая отображается вместе с текущим днем и месяцем. Обратите внимание, что результат отображает соответствующий локализованный текст, за исключением случаев, когда текущая культура пользовательского интерфейса — шведская (Швеция). Поскольку шведские языковые ресурсы недоступны, приложение вместо этого использует ресурсы языка по умолчанию, которым является английский.
В примере требуются текстовые файлы ресурсов, перечисленные в следующей таблице. Каждый имеет один строковый ресурс с именем DateStart
.
Культура | Имя файла | Имя ресурса | Значение ресурса |
---|---|---|---|
en-US | DateStrings.txt | DateStart |
Сегодня |
fr-FR | DateStrings.fr-FR.txt | DateStart |
Сегодня это |
ru-RU | DateStrings.ru-RU.txt | DateStart |
Сегодня |
Ниже приведен исходный код для примера (ShowDate.vb для версии Visual Basic или ShowDate.cs для версии C# кода).
using System;
using System.Globalization;
using System.Resources;
using System.Threading;
[assembly: NeutralResourcesLanguage("en")]
public class ShowDateEx
{
public static void Main()
{
string[] cultureNames = { "en-US", "fr-FR", "ru-RU", "sv-SE" };
ResourceManager rm = new ResourceManager("DateStrings",
typeof(Example).Assembly);
foreach (var cultureName in cultureNames)
{
CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
Console.WriteLine($"Current UI Culture: {CultureInfo.CurrentUICulture.Name}");
string dateString = rm.GetString("DateStart");
Console.WriteLine($"{dateString} {DateTime.Now:M}.\n");
}
}
}
// The example displays output similar to the following:
// Current UI Culture: en-US
// Today is February 03.
//
// Current UI Culture: fr-FR
// Aujourd'hui, c'est le 3 février
//
// Current UI Culture: ru-RU
// Сегодня февраля 03.
//
// Current UI Culture: sv-SE
// Today is den 3 februari.
Imports System.Globalization
Imports System.Resources
Imports System.Threading
<Assembly:NeutralResourcesLanguage("en")>
Module Example5
Public Sub Main()
Dim cultureNames() As String = {"en-US", "fr-FR", "ru-RU", "sv-SE"}
Dim rm As New ResourceManager("DateStrings",
GetType(Example5).Assembly)
For Each cultureName In cultureNames
Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName)
Thread.CurrentThread.CurrentCulture = culture
Thread.CurrentThread.CurrentUICulture = culture
Console.WriteLine("Current UI Culture: {0}",
CultureInfo.CurrentUICulture.Name)
Dim dateString As String = rm.GetString("DateStart")
Console.WriteLine("{0} {1:M}.", dateString, Date.Now)
Console.WriteLine()
Next
End Sub
End Module
' The example displays output similar to the following:
' Current UI Culture: en-US
' Today is February 03.
'
' Current UI Culture: fr-FR
' Aujourd'hui, c'est le 3 février
'
' Current UI Culture: ru-RU
' Сегодня февраля 03.
'
' Current UI Culture: sv-SE
' Today is den 3 februari.
Чтобы скомпилировать этот пример, создайте пакетный файл, содержащий следующие команды, и запустите его из командной строки. Если вы используете C#, укажите csc
вместо vbc
и showdate.cs
вместо showdate.vb
.
resgen DateStrings.txt
vbc showdate.vb /resource:DateStrings.resources
md fr-FR
resgen DateStrings.fr-FR.txt
al /out:fr-FR\Showdate.resources.dll /culture:fr-FR /embed:DateStrings.fr-FR.resources
md ru-RU
resgen DateStrings.ru-RU.txt
al /out:ru-RU\Showdate.resources.dll /culture:ru-RU /embed:DateStrings.ru-RU.resources
Существует два способа получения ресурсов конкретной культуры, отличной от текущей культуры пользовательского интерфейса:
- Можно вызвать метод GetString(String, CultureInfo), GetObject(String, CultureInfo)или GetStream(String, CultureInfo), чтобы получить ресурс для определенной культуры. Если локализованный ресурс не найден, менеджер ресурсов использует процесс отката ресурсов для поиска соответствующего ресурса.
- Метод GetResourceSet можно вызвать для получения объекта ResourceSet, представляющего ресурсы для определенной культуры. В вызове метода можно определить, выполняется ли проба диспетчера ресурсов для родительских языков и региональных параметров, если она не может найти локализованные ресурсы или просто возвращается к ресурсам языка и региональных параметров по умолчанию. Затем можно использовать методы ResourceSet для получения доступа к ресурсам (локализованным для данной культуры) по имени или для перечисления ресурсов в наборе.
Обработка исключений MissingManifestResourceException и MissingSatelliteAssemblyException
Если вы пытаетесь получить определенный ресурс, но диспетчер ресурсов не может найти этот ресурс и не определена ни одна культура по умолчанию, либо локализацию ресурсов по умолчанию невозможно выполнить, диспетчер ресурсов создает исключение MissingManifestResourceException, если он ожидает найти ресурсы в основной сборке, или исключение MissingSatelliteAssemblyException, если он ожидает найти ресурсы в сателлитной сборке. Обратите внимание, что исключение возникает при вызове метода извлечения ресурсов, например GetString или GetObject, а не при создании экземпляра объекта ResourceManager.
Исключение обычно создается в следующих условиях:
Не существует соответствующего файла ресурсов или сателлитной сборки. Если диспетчер ресурсов ожидает, что ресурсы по умолчанию приложения будут внедрены в основную сборку приложений, они отсутствуют. Если атрибут NeutralResourcesLanguageAttribute указывает, что ресурсы приложения по умолчанию находятся в сателлитной сборке, то её найти не удается. При компиляции приложения убедитесь, что ресурсы встроены в основную сборку или создаются необходимые вспомогательные сборки и называются соответствующим образом. Его имя должно принимать форму appName.resources.dll, и он должен находиться в каталоге с именем культуры, ресурсы которой он содержит.
В вашем приложении не определена культура по умолчанию или нейтральная культура. Добавьте атрибут NeutralResourcesLanguageAttribute в файл исходного кода или в файл сведений о проекте (AssemblyInfo.vb для приложения Visual Basic или AssemblyInfo.cs для приложения C#).
Параметр
baseName
в конструкторе ResourceManager(String, Assembly) не задает имя файла .resources. Имя должно содержать полное пространство имен файла ресурсов, но не его расширение файла. Как правило, файлы ресурсов, созданные в Visual Studio, содержат имена пространств имен, но файлы ресурсов, созданные и скомпилированные в командной строке, их не содержат. Вы можете определить имена внедренных файлов ресурсов, скомпилируя и выполнив следующую программу. Это консольное приложение, которое принимает имя основной сборки или вспомогательной сборки в качестве параметра командной строки. В нем отображаются строки, которые должны быть предоставлены в качестве параметраbaseName
, чтобы диспетчер ресурсов правильно идентифицировал ресурс.using System; using System.IO; using System.Reflection; public class Example0 { public static void Main() { if (Environment.GetCommandLineArgs().Length == 1) { Console.WriteLine("No filename."); return; } string filename = Environment.GetCommandLineArgs()[1].Trim(); // Check whether the file exists. if (! File.Exists(filename)) { Console.WriteLine($"{filename} does not exist."); return; } // Try to load the assembly. Assembly assem = Assembly.LoadFrom(filename); Console.WriteLine($"File: {filename}"); // Enumerate the resource files. string[] resNames = assem.GetManifestResourceNames(); if (resNames.Length == 0) Console.WriteLine(" No resources found."); foreach (var resName in resNames) Console.WriteLine($" Resource: {resName.Replace(".resources", "")}"); Console.WriteLine(); } }
Imports System.IO Imports System.Reflection Imports System.Resources Module Example Public Sub Main() If Environment.GetCommandLineArgs.Length = 1 Then Console.WriteLine("No filename.") Exit Sub End If Dim filename As String = Environment.GetCommandLineArgs(1).Trim() ' Check whether the file exists. If Not File.Exists(filename) Then Console.WriteLine("{0} does not exist.", filename) Exit Sub End If ' Try to load the assembly. Dim assem As Assembly = Assembly.LoadFrom(filename) Console.WriteLine("File: {0}", filename) ' Enumerate the resource files. Dim resNames() As String = assem.GetManifestResourceNames() If resNames.Length = 0 Then Console.WriteLine(" No resources found.") End If For Each resName In resNames Console.WriteLine(" Resource: {0}", resName.Replace(".resources", "")) Next Console.WriteLine() End Sub End Module
При изменении текущей культуры приложения явно следует помнить, что диспетчер ресурсов извлекает набор ресурсов на основе значения свойства CultureInfo.CurrentUICulture, а не свойства CultureInfo.CurrentCulture. Как правило, при изменении одного значения следует также изменить другое.
Управление версиями ресурсов
Так как основная сборка, содержащая ресурсы по умолчанию приложения, отделена от вспомогательных сборок приложения, вы можете освободить новую версию основной сборки без повторного развертывания вспомогательных сборок. Атрибут SatelliteContractVersionAttribute применяется для использования существующих спутниковых сборок и указания диспетчеру ресурсов не развёртывать их повторно при обновлении основной сборки.
Дополнительные сведения о поддержке управления версиями вспомогательных сборок см. в статье извлечение ресурсов.
<satelliteassemblies> узел файла конфигурации
Примечание.
Этот раздел предназначен для приложений .NET Framework.
Для исполняемых файлов, развернутых и запускаемых с веб-сайта (HREF .exe файлов), объект ResourceManager может проверять наличие вспомогательных сборок через Интернет, что может ухудшить производительность приложения. Чтобы устранить проблему производительности, можно ограничить это пробование вспомогательными сборками, развернутыми с помощью приложения. Для этого создайте узел <satelliteassemblies>
в файле конфигурации приложения, чтобы указать, что развернут определенный набор языков и региональных параметров для приложения, и что объект ResourceManager не должен пытаться проверить язык и региональные параметры, не перечисленные в этом узле.
Примечание.
Предпочтительным вариантом создания узла <satelliteassemblies>
является использование функции манифеста развертывания ClickOnce .
В файле конфигурации приложения создайте раздел, аналогичный следующему:
<?xml version ="1.0"?>
<configuration>
<satelliteassemblies>
<assembly name="MainAssemblyName, Version=versionNumber, Culture=neutral, PublicKeyToken=null|yourPublicKeyToken">
<culture>cultureName1</culture>
<culture>cultureName2</culture>
<culture>cultureName3</culture>
</assembly>
</satelliteassemblies>
</configuration>
Измените эти сведения о конфигурации следующим образом:
Укажите один или несколько узлов
<assembly>
для каждой основной сборки, где каждый узел указывает полное имя сборки. Укажите имя основной сборки вместо MainAssemblyName, а также укажите значения атрибутовVersion
,PublicKeyToken
иCulture
, соответствующие вашей основной сборке.Для атрибута
Version
укажите номер версии сборки. Например, первый выпуск сборки может быть номером версии 1.0.0.0.Для атрибута
PublicKeyToken
укажите ключевое словоnull
, если сборка не подписана строгим именем или укажите маркер открытого ключа, если вы подписали сборку.Для атрибута
Culture
укажите ключевое словоneutral
, чтобы обозначить основную сборку и чтобы класс ResourceManager проверял только культуры, перечисленные в узлах<culture>
.Для получения дополнительной информации о полностью квалифицированных именах сборок см. статью Имена сборок. Дополнительные сведения о сборках с строгими именами см. в статье Создание и использование сборок с строгими именами.
Укажите один или несколько узлов
<culture>
с указанием конкретного названия культуры, например "fr-FR", или нейтрального названия культуры, например "fr".
Если ресурсы необходимы для любой сборки, не указанной в узле <satelliteassemblies>
, класс ResourceManager проверяет культуры, используя стандартные правила проверки.
Приложения Windows 8.x
Это важно
Хотя класс ResourceManager поддерживается в приложениях Windows 8.x, мы не рекомендуем использовать его. Используйте этот класс только при разработке проектов переносимой библиотеки классов, которые можно использовать с приложениями Windows 8.x. Чтобы получить ресурсы из приложений Windows 8.x, используйте вместо этого класс Windows.ApplicationModel.Resources.ResourceLoader.
Для приложений Windows 8.x класс ResourceManager извлекает ресурсы из файлов индекса ресурсов пакета (PRI). Один файл PRI (PRI-файл пакета приложения) содержит ресурсы как для культуры по умолчанию, так и для всех локализованных культур. Программа MakePRI используется для создания файла PRI из одного или нескольких файлов ресурсов, которые находятся в формате XML-ресурса (RESW). Для ресурсов, включенных в проект Visual Studio, Visual Studio обрабатывает процесс создания и упаковки ФАЙЛА PRI автоматически. Затем можно использовать класс .NET ResourceManager для доступа к ресурсам приложения или библиотеки.
Вы можете создать экземпляр объекта ResourceManager для приложения Windows 8.x таким же образом, как и для классического приложения.
Затем можно получить доступ к ресурсам для определенной культуры, передав имя ресурса, который требуется извлечь, в метод GetString(String). По умолчанию этот метод возвращает ресурс для культуры, определяемой текущей культурой пользовательского интерфейса вызвавшего поток. Вы также можете получить ресурсы для определенной культуры, передав в метод GetString(String, CultureInfo) имя ресурса и объект CultureInfo, представляющий культуру, ресурс которой нужно получить. Если ресурс для текущей языковой культуры пользовательского интерфейса или указанной культуры не найден, диспетчер ресурсов использует список языков резервирования пользовательского интерфейса для поиска подходящего ресурса.
Примеры
В следующем примере показано, как использовать явные региональные параметры и неявные текущие параметры пользовательского интерфейса для получения строковых ресурсов из основной сборки и спутниковой сборки. Дополнительные сведения см. в разделе "Расположения каталогов для вспомогательных сборок, не установленных в глобальном кэше сборок" в теме создание вспомогательных сборок.
Чтобы выполнить этот пример, выполните указанные ниже действия.
В каталоге приложений создайте файл с именем rmc.txt, содержащий следующие строки ресурсов:
day=Friday year=2006 holiday="Cinco de Mayo"
Используйте генератор файлов ресурсов для создания файла ресурсов rmc.resources из входного файла rmc.txt следующим образом:
resgen rmc.txt
Создайте подкаталог каталога приложения и назовите его "es-MX". Это название культуры спутниковой сборки, которую вы создадите в следующих трех шагах.
Создайте файл с именем rmc.es-MX.txt в каталоге es-MX, который содержит следующие строки ресурсов:
day=Viernes year=2006 holiday="Cinco de Mayo"
Используйте генератор файлов ресурсов , чтобы создать файл ресурсов .resourceses-MXиз входного файла rmc.es-MX.txt следующим образом:
resgen rmc.es-MX.txt
Предположим, что имя файла для этого примера — rmc.vb или rmc.cs. Скопируйте следующий исходный код в файл. Затем скомпилируйте его и вставьте файл ресурсов основной сборки rmc.resources в исполняемую сборку. Если вы используете компилятор Visual Basic, синтаксис:
vbc rmc.vb /resource:rmc.resources
Соответствующий синтаксис компилятора C#:
csc /resource:rmc.resources rmc.cs
Используйте компоновщик сборки для создания спутниковой сборки. Если базовое имя приложения — rmc, имя сателлитной сборки должно быть rmc.resources.dll. Спутниковая сборка должна быть создана в каталоге es-MX. Если es-MX является текущим каталогом, используйте следующую команду:
al /embed:rmc.es-MX.resources /c:es-MX /out:rmc.resources.dll
Запустите rmc.exe, чтобы получить и отобразить внедренные строки ресурсов.
using System; using System.Globalization; using System.Resources; class Example2 { public static void Main() { string day; string year; string holiday; string celebrate = "{0} will occur on {1} in {2}.\n"; // Create a resource manager. ResourceManager rm = new ResourceManager("rmc", typeof(Example).Assembly); Console.WriteLine("Obtain resources using the current UI culture."); // Get the resource strings for the day, year, and holiday // using the current UI culture. day = rm.GetString("day"); year = rm.GetString("year"); holiday = rm.GetString("holiday"); Console.WriteLine(celebrate, holiday, day, year); // Obtain the es-MX culture. CultureInfo ci = new CultureInfo("es-MX"); Console.WriteLine("Obtain resources using the es-MX culture."); // Get the resource strings for the day, year, and holiday // using the specified culture. day = rm.GetString("day", ci); year = rm.GetString("year", ci); holiday = rm.GetString("holiday", ci); // --------------------------------------------------------------- // Alternatively, comment the preceding 3 code statements and // uncomment the following 4 code statements: // ---------------------------------------------------------------- // Set the current UI culture to "es-MX" (Spanish-Mexico). // Thread.CurrentThread.CurrentUICulture = ci; // Get the resource strings for the day, year, and holiday // using the current UI culture. Use those strings to // display a message. // day = rm.GetString("day"); // year = rm.GetString("year"); // holiday = rm.GetString("holiday"); // --------------------------------------------------------------- // Regardless of the alternative that you choose, display a message // using the retrieved resource strings. Console.WriteLine(celebrate, holiday, day, year); } } /* This example displays the following output: Obtain resources using the current UI culture. "5th of May" will occur on Friday in 2006. Obtain resources using the es-MX culture. "Cinco de Mayo" will occur on Viernes in 2006. */
Imports System.Resources Imports System.Reflection Imports System.Threading Imports System.Globalization Class Example4 Public Shared Sub Main() Dim day As String Dim year As String Dim holiday As String Dim celebrate As String = "{0} will occur on {1} in {2}." & vbCrLf ' Create a resource manager. Dim rm As New ResourceManager("rmc", GetType(Example4).Assembly) Console.WriteLine("Obtain resources using the current UI culture.") ' Get the resource strings for the day, year, and holiday ' using the current UI culture. day = rm.GetString("day") year = rm.GetString("year") holiday = rm.GetString("holiday") Console.WriteLine(celebrate, holiday, day, year) ' Obtain the es-MX culture. Dim ci As New CultureInfo("es-MX") Console.WriteLine("Obtain resources using the es-MX culture.") ' Get the resource strings for the day, year, and holiday ' using the es-MX culture. day = rm.GetString("day", ci) year = rm.GetString("year", ci) holiday = rm.GetString("holiday", ci) ' --------------------------------------------------------------- ' Alternatively, comment the preceding 3 code statements and ' uncomment the following 4 code statements: ' ---------------------------------------------------------------- ' Set the current UI culture to "es-MX" (Spanish-Mexico). ' Thread.CurrentThread.CurrentUICulture = ci ' Get the resource strings for the day, year, and holiday ' using the current UI culture. ' day = rm.GetString("day") ' year = rm.GetString("year") ' holiday = rm.GetString("holiday") ' --------------------------------------------------------------- ' Regardless of the alternative that you choose, display a message ' using the retrieved resource strings. Console.WriteLine(celebrate, holiday, day, year) End Sub End Class ' This example displays the following output: 'Obtain resources using the current UI culture. '"5th of May" will occur on Friday in 2006. ' 'Obtain resources using the es-MX culture. '"Cinco de Mayo" will occur on Viernes in 2006.