Класс System.Resources.ResourceManager
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Важно!
Вызов методов этого класса для ненадежных данных представляет угрозу безопасности. Вызывайте методы класса только для надежных данных. Дополнительные сведения см. в разделе "Проверка всех входных данных".
Класс ResourceManager извлекает ресурсы из двоичного файла .resources, внедренного в сборку или из автономного файла ресурсов. Если приложение было локализовано и локализовано в вспомогательных сборках, оно ищет ресурсы, зависящие от языка и региональных параметров, предоставляет резервный вариант ресурсов, если локализованный ресурс не существует, и поддерживает сериализацию ресурсов.
Классические приложения
Для классических приложений ResourceManager класс извлекает ресурсы из двоичных файлов ресурсов (.resources). Как правило, компилятор языка или компоновщик сборок (AL.exe) внедряет эти файлы ресурсов в сборку. Вы также можете использовать ResourceManager объект для извлечения ресурсов непосредственно из файла РЕСУРСОВ, который не внедрен в сборку, вызывая CreateFileBasedResourceManager метод.
Внимание
Использование автономных файлов ресурсов в приложении ASP.NET прерывает развертывание XCOPY, так как ресурсы остаются заблокированными, пока они не будут явно освобождены методом ReleaseAllResources . Если вы хотите развернуть ресурсы с помощью приложений ASP.NET, необходимо скомпилировать файлы ресурсов в вспомогательные сборки.
В приложении на основе ресурсов один файл ресурсов содержит ресурсы языка и региональных параметров по умолчанию, ресурсы которых используются, если ресурсы, относящиеся к языку и региональным параметрам, не найдены. Например, если язык и региональные параметры по умолчанию приложения — английский (en), ресурсы английского языка используются всякий раз, когда локализованные ресурсы не могут быть найдены для определенного языка и региональных параметров, таких как английский (США) (en-US) или французский (Франция) (fr-FR). Как правило, ресурсы для языка и региональных параметров по умолчанию внедрены в основную сборку приложения, а ресурсы для других локализованных языков и региональных параметров внедрены в вспомогательные сборки. Вспомогательные сборки содержат только ресурсы. Они имеют то же имя корневого файла, что и основная сборка и расширение .resources.dll. Для приложений, сборки которых не зарегистрированы в глобальном кэше сборок, вспомогательные сборки хранятся в подкаталоге приложения, имя которого соответствует языку и региональным параметрам сборки.
Создание ресурсов
При разработке приложения на основе ресурсов хранятся сведения о ресурсах в текстовых файлах (файлы с расширением restext .txt или RESTEXT) или XML-файлы (файлы с расширением RESX). Затем вы компилируете текстовые или XML-файлы с помощью генератора файлов ресурсов (Resgen.exe), чтобы создать двоичный файл ресурсов. Затем можно внедрить результирующий файл ресурсов в исполняемый файл или библиотеку с помощью параметра компилятора, /resources
например для компиляторов C# и Visual Basic, или внедрить его в спутниковую сборку с помощью компоновщика сборок (AI.exe). Если в проект Visual Studio включен RESX-файл, Visual Studio обрабатывает компиляцию и внедрение стандартных и локализованных ресурсов автоматически в процессе сборки.
В идеале следует создавать ресурсы для каждого языка, который поддерживает приложение, или по крайней мере для понятного подмножества каждого языка. Имена файлов двоичных ресурсов соответствуют базовому имени соглашения об именовании.cultureName.resources, где basename — это имя приложения или имя класса в зависимости от нужного уровня детализации. Свойство CultureInfo.Name используется для определения языка и региональных параметров. Ресурс для языка и региональных параметров по умолчанию приложения должен называться basename.resources.
Например, предположим, что сборка содержит несколько ресурсов в файле ресурсов с базовым именем MyResources. Эти файлы ресурсов должны иметь такие имена, как MyResources.ja-JP.resources для японии (японского) языка, MyResources.de.resources для немецкого языка и региональных параметров, MyResources.zh-CHS.resources для упрощенного китайского языка и myResources.fr-BE.resources для французского языка (Бельгия). Файл ресурсов по умолчанию должен называться MyResources.resources. Файлы ресурсов, зависящие от языка и региональных параметров, обычно упаковываются в вспомогательные сборки для каждого языка и региональных параметров. Файл ресурсов по умолчанию должен быть внедрен в основную сборку приложения.
Обратите внимание, что компоновщик сборок позволяет ресурсам помечены как частные, но их всегда следует пометить как общедоступные, чтобы они могли получить доступ к другим сборкам. (Так как в вспомогательной сборке нет кода, ресурсы, помеченные как частные, недоступны для приложения с помощью любого механизма.)
Дополнительные сведения о создании, упаковке и развертывании ресурсов см. в статьях "Создание файлов ресурсов", "Создание вспомогательных сборок" и "Упаковка" и "Развертывание ресурсов".
Создание экземпляра объекта ResourceManager
Создается экземпляр ResourceManager объекта, который извлекает ресурсы из внедренного файла ресурсов .resources, вызывая одну из перегрузок конструктора классов. Это тесно связывает ResourceManager объект с определенным файлом ресурсов и любым связанными локализованными файлами ресурсов в вспомогательных сборках.
Два наиболее часто называемых конструктора:
ResourceManager(String, Assembly) ищет ресурсы на основе двух частей информации, которые вы предоставляете: базовое имя файла ресурсов и сборку, в которой находится файл ресурсов по умолчанию. Базовое имя включает пространство имен и корневое имя файла ресурсов без его языка и региональных параметров или расширения. Обратите внимание, что файлы ресурсов, скомпилированные из командной строки, обычно не включают имя пространства имен, а файлы ресурсов, созданные в среде 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 экземпляр объекта, который может получить ресурсы из файла .resources:ResourceManager rm = new ResourceManager(typeof(MyCompany.StringResources));
Dim rm As New ResourceManager(GetType(MyCompany.StringResources))
Если не удается найти соответствующие ресурсы, вызов конструктора создает допустимый ResourceManager объект. Однако попытка получить ресурс создает MissingManifestResourceException исключение. Сведения о работе с исключением см . в разделе "Обработка missingManifestResourceException и MissingSatelliteAssemblyException Exceptions " далее в этой статье.
В следующем примере показано, как создать экземпляр 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("{0} {1:T}", timeString, DateTime.Now);
}
}
// 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 {0}", 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 исключение. Сведения о работе с исключением см . в разделе "Обработка missingManifestResourceException и MissingSatelliteAssemblyException Exceptions " далее в этой статье.
В следующем примере метод используется для получения ресурсов, относящихся к языку GetString и региональных параметров. Он состоит из ресурсов, скомпилированных из .txt файлов для английского языка (en), французского (Франция) (fr-FR) и российских (Россия) культур (ru-RU). В примере изменяется текущий язык и региональные параметры пользовательского интерфейса на английский (США), французский (Франция), русский (Россия) и шведский (Швеция). Затем он вызывает GetString метод для получения локализованной строки, которая отображается вместе с текущим днем и месяцем. Обратите внимание, что выходные данные отображают соответствующую локализованную строку, за исключением случаев, когда текущий язык и региональные параметры пользовательского интерфейса — шведский (Швеция). Так как шведские языковые ресурсы недоступны, приложение вместо этого использует ресурсы языка и региональных параметров по умолчанию, которые являются английскими.
В примере требуются текстовые файлы ресурсов, перечисленные в следующей таблице. Каждый имеет один строковый ресурс с именем DateStart
.
Культура | Имя файла | Имя ресурса | Значение ресурса |
---|---|---|---|
en-US | DateStrings.txt | DateStart |
Сегодня |
fr-FR | DateStrings.fr-FR.txt | DateStart |
Aujourd'hui, c'est le |
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: {0}",
CultureInfo.CurrentUICulture.Name);
string dateString = rm.GetString("DateStart");
Console.WriteLine("{0} {1:M}.\n", dateString, DateTime.Now);
}
}
}
// 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 Если атрибут указывает, что ресурсы по умолчанию приложения находятся в вспомогательной сборке, то не удается найти ее. При компиляции приложения убедитесь, что ресурсы встроены в основную сборку или создаются необходимые вспомогательные сборки и называются соответствующим образом. Его имя должно принимать имя приложения формы.resources.dll, и оно должно находиться в каталоге с именем языка и региональных параметров, ресурсы которых он содержит.
Приложение не имеет определенного по умолчанию или нейтрального языка и региональных параметров. Добавьте атрибут в NeutralResourcesLanguageAttribute файл исходного кода или в файл сведений о проекте (AssemblyInfo.vb для приложения Visual Basic или AssemblyInfo.cs для приложения C#).
Параметр
baseName
в конструкторе ResourceManager(String, Assembly) не указывает имя файла ресурсов. Имя должно содержать полное пространство имен файла ресурсов, но не его расширение имени файла. Как правило, файлы ресурсов, созданные в 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("{0} does not exist.", filename); return; } // Try to load the assembly. Assembly assem = Assembly.LoadFrom(filename); Console.WriteLine("File: {0}", 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: {0}", 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.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 .
Для приложений ResourceManager Windows 8.x класс извлекает ресурсы из файлов индекса ресурсов пакета (PRI). Один файл PRI (PRI-файл пакета приложения) содержит ресурсы как для языка и региональных параметров по умолчанию, так и для всех локализованных языков и региональных параметров. Программа MakePRI используется для создания файла PRI из одного или нескольких файлов ресурсов, которые находятся в формате XML-ресурса (RESW). Для ресурсов, включенных в проект Visual Studio, Visual Studio обрабатывает процесс создания и упаковки ФАЙЛА PRI автоматически. Затем можно использовать класс .NET ResourceManager для доступа к ресурсам приложения или библиотеки.
Вы можете создать экземпляр ResourceManager объекта для приложения Windows 8.x таким же образом, как и для классического приложения.
Затем вы можете получить доступ к ресурсам для определенного языка и региональных параметров, передав имя ресурса, который необходимо получить в GetString(String) метод. По умолчанию этот метод возвращает ресурс для языка и региональных параметров, определенных текущим языком и региональными параметрами пользовательского интерфейса потока, который сделал вызов. Вы также можете получить ресурсы для определенного языка и региональных параметров, передав имя ресурса и CultureInfo объект, представляющий язык и региональные параметры, ресурс которых требуется извлечь в GetString(String, 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"
Используйте генератор файлов ресурсов для создания файла ресурсов rmc.es-MX.resources из входного файла 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.