Создание вспомогательных сборок для приложений .NET
Файлы ресурсов играют важную роль в локализованных приложениях. Они позволяют приложению отображать строки, изображения и другие данные на языке пользователя и региональных параметрах, а также предоставлять альтернативные данные, если ресурсы для языка пользователя или языка и региональных параметров недоступны. .NET использует модель концентратора и периферийной среды для поиска и извлечения локализованных ресурсов. Центром в этой модели является основная сборка, которая содержит не локализуемый исполняемый код и ресурсы для единственного языка и региональных параметров, называемых нейтральными языком и региональными параметрами, или региональными настройками по умолчанию. Язык и региональные параметры по умолчанию — это резервный язык и региональные параметры для приложения; он используется, если локализованные ресурсы недоступны. Атрибут NeutralResourcesLanguageAttribute используется для указания языка и региональных параметров по умолчанию для приложения. Каждый луч звезды ведет к вспомогательной сборке, которая содержит ресурсы для одного локализованного языка и региональных параметров, но не содержит кода. Так как вспомогательные сборки не являются частью основной сборки, вы можете легко обновлять или заменять ресурсы, соответствующие определенному языку и региональным параметрам, не заменяя основную сборку для приложения.
Примечание.
Ресурсы языка и региональных параметров по умолчанию приложения также могут храниться и во вспомогательной сборке. Для этого нужно назначить атрибуту NeutralResourcesLanguageAttribute значение UltimateResourceFallbackLocation.Satellite.
Имя и расположение вспомогательной сборки
Для реализации модели "звезда" необходимо разместить ресурсы в определенных местах так, чтобы их можно было легко найти и использовать. Если вы не компилируете и не будете именовать ресурсы должным образом или не помещать их в правильные расположения, среда CLR не сможет найти их и будет использовать ресурсы языка и региональных параметров по умолчанию. Диспетчер ресурсов .NET представлен типом ResourceManager и используется для автоматического доступа к локализованным ресурсам. Для диспетчера ресурсов требуется следующее:
Одна вспомогательная сборка должна включать все ресурсы для определенных языка и региональных параметров. Иначе говоря, необходимо скомпилировать несколько файлов .txt или .resx в двоичный файл .resources.
Для каждого локализованного языка и региональных параметров, где содержатся ресурсы для языка и региональных параметров, должен быть выделен отдельный вложенный каталог. Имя вложенного каталога должно совпадать с именем языка и региональных параметров. Кроме того, можно хранить вспомогательные сборки в глобальном кэше сборок. В этом случае компонент данных языка и региональных параметров строгого имени сборки должен указывать на свой язык и региональные параметры. Дополнительные сведения см. в разделе Установка вспомогательных сборок в глобальный кэш сборок.
Примечание.
Если приложение содержит ресурсы для дочерних языков и региональных параметров, поместите каждый дочерний язык и региональные параметры в отдельный вложенный подкаталог в каталоге приложения. Не следует размещать дочерние языки и региональных параметры во вложенных каталогах каталога основного языка и региональных параметров.
Вспомогательная сборка должна иметь то же имя, что и приложение, а также должна использовать расширение имени файла ".resources.dll". Например, если приложение называется Example.exe, то именем каждой вспомогательной сборки должно быть Example.resources.dll. Имя вспомогательной сборки не указывает язык и региональные параметры файлов ресурсов. Но вспомогательная сборка отображается в каталоге, который указывает на определенные язык и региональные параметры.
Сведения о языке и региональных параметрах вспомогательной сборки должны быть включены в метаданных сборки. Чтобы сохранить имя языка и региональных параметров в метаданных вспомогательной сборки, необходимо задать параметр
/culture
при использовании компоновщика сборок для внедрения ресурсов во вспомогательную сборку.
На следующем рисунке показаны примеры требований к структуре каталогов и расположению для приложений, которые не устанавливаются в глобальном кэше сборок. Элементы с расширениями .txt и .resources не будут отправляться с конечным приложением. Они представляют собой промежуточные файлы ресурсов, используемые для создания итоговых вспомогательных сборок ресурсов. В этом примере можно заменить RESX-файлы для .txt файлов. Дополнительные сведения см. в статье Упаковка и развертывание ресурсов.
На следующем изображении показан каталог вспомогательных сборок:
Компиляция вспомогательных сборок
Используйте генератор файлов ресурсов (resgen.exe) для компиляции текстовых файлов или файлов XML (RESX), содержащих ресурсы, в двоичные RESOURCES-файлы. Используйте компоновщик сборок (al.exe) для компиляции RESOURCES-файлов во вспомогательные сборки. Программа al.exe создает сборку из указанных RESOURCES-файлов. Вспомогательные сборки могут содержать только ресурсы; Они не могут содержать исполняемый код.
Следующая команда al.exe служит для создания вспомогательной сборки со строгим именем для приложения Example
из файла ресурсов региональных настроек Германии strings.de.resources.
al -target:lib -embed:strings.de.resources -culture:de -out:Example.resources.dll
Следующая команда al.exe служит для создания вспомогательной сборки для приложения Example
из файла strings.de.resources. Параметр /template служит для наследования вспомогательной сборкой всех метаданных сборки, за исключением сведений о языке и региональных параметров ее родительской сборки (Example.dll).
al -target:lib -embed:strings.de.resources -culture:de -out:Example.resources.dll -template:Example.dll
В приведенной ниже таблице более подробно описываются параметры al.exe, используемые в этих командах:
Вариант | Описание |
---|---|
-target:lib |
Указывает, что вспомогательная сборка компилируется в файл библиотеки (DLL). Так как вспомогательные сборки не содержат исполняемый код и не является основной сборкой приложения, необходимо сохранить вспомогательные сборки в виде БИБЛИОТЕК DLL. |
-embed:strings.de.resources |
Указывает для программы al.exe имя файла ресурсов, включенного при компиляции сборки. Во вспомогательной сборке можно включить несколько файлов ресурсов, но если следовать модели "звезда", то необходимо компилировать отдельную вспомогательную сборку для каждого языка и региональных параметров. Впрочем, можно создавать и отдельные RESOURCES-файлы для строк и объектов. |
-culture:de |
Задает язык и региональные параметры компилируемого ресурса. Среда CLR использует эти сведения в процессе поиска ресурсов, относящихся к указанному языку и региональным параметрам. Если этот параметр не указан, al.exe по-прежнему компилирует ресурс, но среда выполнения не сможет найти его, когда пользователь запрашивает его. |
-out:Example.resources.dll |
Указывает имя выходного файла. Имя должно соответствовать шаблону baseName.resources.extension, где baseName — имя основной сборки, а extension — допустимое расширение имени файла (например, DLL). Среда выполнения не может определить язык и региональные параметры вспомогательной сборки на основе имени выходного файла; Для указания параметра /culture необходимо использовать параметр /culture . |
-template:Example.dll |
Задает сборку, от которой наследуют все метаданные сборки, кроме поля языка и региональных параметров. Этот параметр влияет на вспомогательные сборки только в том случае, если указана сборка, у которой есть строгое имя. |
Полный список параметров, доступных в программе al.exe, см. в разделе Компоновщик сборок (al.exe).
Примечание.
Иногда может потребоваться использовать задачу MSBuild .NET Core для компиляции вспомогательных сборок, даже если вы используете платформа .NET Framework. Например, можно использовать детерминированный параметр компилятора C# для сравнения сборок из разных сборок. В этом случае задайте в файле CSPROJ значение GenerateSatelliteAssembliesForCoretrue
, чтобы создать вспомогательные сборки с помощью csc.exe вместо Al.exe (Компоновщик сборок).
<Project>
<PropertyGroup>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
</PropertyGroup>
</Project>
Задача MSBuild .NET Core использует csc.exe вместо al.exe для создания вспомогательных сборок по умолчанию. Дополнительные сведения см. в статье "Упрощение использования вспомогательной сборки Core".
Пример вспомогательных сборок
Ниже приведен простой пример "Hello world", который отображает окно сообщения, содержащее локализованное приветствие. Пример включает ресурсы для английского (США), французского (Франция) и русского (Россия) языка; в качестве нейтрального языка выступает английский. Для создания этого примера выполните следующие действия.
Создайте файл ресурсов с именем Greeting.resx или Greeting.txt, который будет содержать ресурсы для языка и региональных параметров по умолчанию. Сохраните одну строку с именем
HelloString
"Hello world!" в этом файле.Чтобы указать, что язык и региональные параметры по умолчанию для приложения — английский (en), необходимо добавить в файл AssemblyInfo приложения или в главный файл исходного кода, которые будут скомпилированы в основную сборку приложения, следующий атрибут System.Resources.NeutralResourcesLanguageAttribute.
[assembly: NeutralResourcesLanguage("en")]
<Assembly: NeutralResourcesLanguage("en")>
Добавьте поддержку дополнительных языков и региональных параметров (
en-US
,fr-FR
иru-RU
) в приложение следующим образом.Для поддержки языка и региональных параметров
en-US
или "Английский (США)" создайте файл ресурсов с именем Greeting.en-US.resx или Greeting.en-US.txt и сохраните в нем одну строку с именемHelloString
и значением "Hi world!".Для поддержки языка и региональных параметров
fr-FR
или "Французский (Франция)" создайте файл ресурсов с именем Greeting.fr-FR.resx или Greeting.fr-FR.txt и сохраните в нем одну строку с именемHelloString
и значением "Salut tout le monde!".Для поддержки языка и региональных параметров
ru-RU
или "Русский (Россия)" создайте файл ресурсов с именем Greeting.ru-RU.resx или Greeting.ru-RU.txt и сохраните в нем одну строку с именемHelloString
, значением которой является "Всем привет!".
Используйте resgen.exe для компиляции каждого текстового файла или файла ресурсов XML в двоичный RESOURCES-файл. Выходными данными будет набор файлов, имеющий то же корневое имя файла, что и RESX- и TXT-файлы, но с расширением RESOURCES. При создании примера с помощью Visual Studio процесс компиляции отрегулируется автоматически. Если используется среда, отличная от Visual Studio, выполните следующие команды для компиляции RESX-файлов в RESOURCES-файлы:
resgen Greeting.resx resgen Greeting.en-us.resx resgen Greeting.fr-FR.resx resgen Greeting.ru-RU.resx
Если ресурсы располагаются в текстовых файлах вместо XML-файлов, замените расширение RESX на TXT.
Скомпилируйте следующий исходный код и ресурсы для языка и региональных параметров по умолчанию в основную сборку приложения:
Внимание
При использовании командной строки, а не Visual Studio, для создания примера, необходимо изменить вызов конструктора класса ResourceManager на следующий:
ResourceManager rm = new ResourceManager("Greeting", typeof(Example).Assembly);
using System; using System.Globalization; using System.Reflection; using System.Resources; using System.Threading; using System.Windows.Forms; class Example { 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; try { CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]); Thread.CurrentThread.CurrentCulture = newCulture; Thread.CurrentThread.CurrentUICulture = newCulture; ResourceManager rm = new ResourceManager("Example.Greeting", typeof(Example).Assembly); string greeting = String.Format("The current culture is {0}.\n{1}", Thread.CurrentThread.CurrentUICulture.Name, rm.GetString("HelloString")); MessageBox.Show(greeting); } catch (CultureNotFoundException e) { Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName); } finally { Thread.CurrentThread.CurrentCulture = originalCulture; Thread.CurrentThread.CurrentUICulture = originalCulture; } } }
Imports System.Globalization Imports System.Resources Imports System.Threading Module Module1 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 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, My.Resources.Greetings.HelloString) MsgBox(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
Если приложение называется Примером и компилируетсяе из командной строки, выполните команду для компилятора C#:
csc Example.cs -res:Greeting.resources
Соответствующая команда для компилятора Visual Basic имеет вид:
vbc Example.vb -res:Greeting.resources
Создайте вложенный каталог в каталоге основного приложения для каждого локализованного языка и региональных параметров, поддерживаемых приложением. Необходимо создать вложенные каталоги en-US, fr-FR и ru-RU. Visual Studio автоматически создает эти вложенные каталоги в процессе компиляции.
Внедрите отдельные RESOURCES-файлы для определенного языка и региональных параметров во вспомогательные сборки и сохраните их в соответствующем каталоге. Для этого можно воспользоваться командой для каждого RESOURCES-файла:
al -target:lib -embed:Greeting.culture.resources -culture:culture -out:culture\Example.resources.dll
где culture — имя языка и региональных параметров, ресурсы которых содержит вспомогательная сборка. Visual Studio автоматически обрабатывает этот процесс.
Затем можно запустить пример. Он будет случайным образом выбирать один из поддерживаемых языков и региональных параметров и отображать локализованное приветствие.
Установка вспомогательных сборок в глобальный кэш сборок
Вместо установки сборок во вложенном каталоге локального приложения их можно установить в глобальный кэш сборок. Это особенно полезно, если библиотеки классов и сборки ресурсов библиотеки классов используются несколькими приложениями.
Все сборки, устанавливаемые в глобальный кэш сборок, должны иметь строгие имена. Сборки со строгими именами должны быть подписаны допустимой парой открытого и закрытого ключей. Они содержат сведения о версии, с помощью которых среда выполнения определяет, какую сборку следует использовать для удовлетворения запроса привязки. Дополнительные сведения о строгих именах и управлении версиями см. в разделе Управление версиями сборки. Дополнительные сведения о строгих именах см. в разделе Сборки со строгими именами.
При разработке приложения маловероятно, что у вас будет доступ к последней паре открытых и закрытых ключей. Чтобы установить спутниковую сборку в глобальном кэше сборок и убедиться, что она работает должным образом, можно использовать метод, называемый отложенной подписью. Если подписание сборки откладывается, во время построения в файле резервируется место для подписи строгим именем. Фактически подписание откладывается до того момента, когда становится доступной итоговая пара открытого и закрытого ключей. Дополнительные сведения об отложенной подписи см. в разделе Отложенная подпись сборки.
Получение открытого ключа
Чтобы отложить подпись сборки, необходимо иметь доступ к открытому ключу. Открытый ключ можно либо получить в организации, которая будет заниматься окончательным подписанием, либо создать самостоятельно с помощью программы строгих имен (sn.exe).
Следующая команда Sn.exe создает тестовые пары открытого и закрытого ключей. Параметр –k указывает, что Sn.exe необходимо создать новую пару ключей и сохранить ее в заданном файле с именем TestKeyPair.snk.
sn –k TestKeyPair.snk
Открытый ключ можно извлечь из файла, содержащего тестовую пару ключей. Следующая команда извлекает открытый ключ из TestKeyPair.snk и сохраняет его в PublicKey.snk:
sn –p TestKeyPair.snk PublicKey.snk
Отложенная подпись сборки
После получения или создания открытого ключа, можно скомпилировать сборку и указать отложенную подпись, используя компоновщик сборок (al.exe).
Следующая команда al.exe служит для создания вспомогательной сборки со строгим именем для приложения StringLibrary из файла strings.ja.resources:
al -target:lib -embed:strings.ja.resources -culture:ja -out:StringLibrary.resources.dll -delay+ -keyfile:PublicKey.snk
Параметр -delay+ указывает, что компоновщик сборок должен отложить подпись сборки. Параметр -keyfile задает имя файла ключа, в котором содержится открытый ключ, применяемый для откладывания подписи сборки.
Повторная подпись сборки
Прежде чем развертывать приложение, можно заново подписать вспомогательную сборку, подписание которой было отложено, реальной парой ключей. Это можно сделать с помощью программы Sn.exe.
Следующая команда Sn.exe используется для подписи StringLibrary.resources.dll парой ключей, хранящихся в файле RealKeyPair.snk. Параметр –R указывает, что нужно заново подписать сборку с отложенной подписью или сборку, которая должна быть подписана заново.
sn –R StringLibrary.resources.dll RealKeyPair.snk
Установка вспомогательной сборки в глобальный кэш сборок
Когда среда выполнения ищет ресурсы в процессе перехода на резервные средства, в первую очередь она ищет глобальный кэш сборок. (Дополнительные сведения см. в разделе "Резервный процесс ресурсов" разделаУпаковка и развертывание ресурсов.) Как только спутниковая сборка подписана строгим именем, ее можно установить в глобальном кэше сборок с помощью средства глобального кэша сборок (gacutil.exe).
Следующая команда Gacutil.exe устанавливает StringLibrary.resources.dll* в глобальный кэш сборок:
gacutil -i:StringLibrary.resources.dll
Параметр /i указывает программе Gacutil.exe, что данную сборку требуется установить в глобальный кэш сборок. После того, как вспомогательная сборка установлена в кэше, ресурсы, которые она содержит, становятся доступны для всех приложений, которые предназначены для использования вспомогательной сборки.
Пример ресурсов в глобальном кэше сборок
В следующем примере метод в библиотеке классов .NET используется для извлечения и возврата локализованного приветствия из файла ресурса. Библиотека и ее ресурсы зарегистрированы в глобальном кэше сборок. Пример включает ресурсы для английского (США), французского (Франция), русского (Россия) и английского языков и региональных параметров. Английский является языком по умолчанию; ресурсы для него хранятся в основной сборке. Пример первоначально подписывает библиотеку и вспомогательные сборки с открытым ключом, а затем повторно подписывает их парой открытого и закрытого ключа. Для создания этого примера выполните следующие действия.
Если вы не используете Visual Studio, используйте следующую команду средства строгого имени (Sn.exe), чтобы создать пару открытого и закрытого ключа с именем ResKey.snk:
sn –k ResKey.snk
Если вы используете Visual Studio, используйте вкладку "Подписывание" диалогового окна "Свойства проекта" для создания файла ключа.
Используйте следующую команду средства строгих имен (Sn.exe), чтобы создать файл открытого ключа с именем PublicKey.snk:
sn –p ResKey.snk PublicKey.snk
Создайте файл ресурсов с именем Strings.resx, который будет содержать ресурсы для языка и региональных параметров по умолчанию. Сохраните одну строку с именем
Greeting
, значение которой — "Как вы делаете?" в этом файле.Чтобы указать, что язык и региональные параметры по умолчанию для приложения — "en", необходимо добавить в файл AssemblyInfo приложения или в главный файл исходного кода, которые будут скомпилированы в основную сборку приложения, следующий атрибут System.Resources.NeutralResourcesLanguageAttribute:
[assembly:NeutralResourcesLanguageAttribute("en")]
<Assembly: NeutralResourcesLanguageAttribute("en")>
Добавьте поддержку дополнительных языков и региональных параметров (en-US, fr-FR и ru-RU) в приложение следующим образом.
Для поддержки региональных настроек "en-US" (английского языка, США) создайте файл ресурсов с именем Strings.en-US.resx или Strings.en-US.txt и сохраните в нем одну строку с именем
Greeting
и значением "Hello!".Для поддержки языка и региональных параметров "fr-FR" (французского языка, Франция) создайте файл ресурсов с именем Strings.fr-FR.resx или Strings.fr-FR.txt и сохраните в нем одну строку с именем
Greeting
и значением "Bon jour!".Для поддержки языка и региональных параметров "ru-RU" (русского языка, Россия) создайте файл ресурсов с именем Strings.ru-RU.resx или Strings.ru-RU.txt и сохраните в нем одну строку с именем
Greeting
и значением "Привет!".
Используйте resgen.exe для компиляции каждого текстового файла или файла ресурсов XML в двоичный RESOURCES-файл. Выходными данными будет набор файлов, имеющий то же корневое имя файла, что и RESX- и TXT-файлы, но с расширением RESOURCES. При создании примера с помощью Visual Studio процесс компиляции отрегулируется автоматически. Если используется среда, отличная от Visual Studio, выполните следующую команду для компиляции RESX-файлов в RESOURCES-файлы:
resgen filename
Где filename — дополнительный путь, имя и расширение RESX-файла или текстового файла.
Скомпилируйте следующий исходный код для StringLibrary.vb или StringLibrary.cs с ресурсами для региональных настроек по умолчанию в библиотеки сборки с отложенной подписью с именем StringLibrary.dll:
Внимание
При использовании командной строки, а не Visual Studio, для создания примера следует изменить вызов конструктора класса ResourceManager на следующий:
ResourceManager rm = new ResourceManager("Strings",
typeof(Example).Assembly);
.using System; using System.Globalization; using System.Reflection; using System.Resources; using System.Threading; [assembly:NeutralResourcesLanguageAttribute("en")] public class StringLibrary { public string GetGreeting() { ResourceManager rm = new ResourceManager("Strings", Assembly.GetAssembly(typeof(StringLibrary))); string greeting = rm.GetString("Greeting"); return greeting; } }
Imports System.Globalization Imports System.Reflection Imports System.Resources Imports System.Threading <Assembly: NeutralResourcesLanguageAttribute("en")> Public Class StringLibrary Public Function GetGreeting() As String Dim rm As New ResourceManager("Strings", _ Assembly.GetAssembly(GetType(StringLibrary))) Dim greeting As String = rm.GetString("Greeting") Return greeting End Function End Class
Команда для компилятора C# имеет вид:
csc -t:library -resource:Strings.resources -delaysign+ -keyfile:publickey.snk StringLibrary.cs
Соответствующая команда для компилятора Visual Basic имеет вид:
vbc -t:library -resource:Strings.resources -delaysign+ -keyfile:publickey.snk StringLibrary.vb
Создайте вложенный каталог в каталоге основного приложения для каждого локализованного языка и региональных параметров, поддерживаемых приложением. Необходимо создать вложенные каталоги en-US, fr-FR и ru-RU. Visual Studio автоматически создает эти вложенные каталоги в процессе компиляции. Так как все вспомогательные сборки имеют одно и то же имя файла, вложенные каталоги используются для хранения отдельных вспомогательных сборок и региональных параметров, пока они не будут подписаны с парой открытого и закрытого ключа.
Внедрите отдельные RESOURCES-файлы ресурсов для определенного языка и региональных параметров во вспомогательные сборки с отложенной подписью и сохраните в соответствующем каталоге. Для этого можно воспользоваться командой для каждого RESOURCES-файла:
al -target:lib -embed:Strings.culture.resources -culture:culture -out:culture\StringLibrary.resources.dll -delay+ -keyfile:publickey.snk
где culture — название языка и региональных параметров. В этом примере имена региональных настроек: en-US, fr-FR, и ru-RU.
Подпишите заново StringLibrary.dll с помощью средства строгих имен (sn.exe) следующим образом:
sn –R StringLibrary.dll RealKeyPair.snk
Подпишите заново отдельные вспомогательные сборки. Для этого используйте средство строгих имен (sn.exe) для каждой вспомогательной сборки, как показано ниже:
sn –R StringLibrary.resources.dll RealKeyPair.snk
Зарегистрируйте StringLibrary.dll и все вспомогательные сборки в глобальном кэше сборок с помощью следующей команды:
gacutil -i filename
где filename — имя регистрируемого файла.
Если вы используете Visual Studio, создайте проект консольного приложения с именем
Example
, добавьте ссылку на StringLibrary.dll и следующий исходный код в него и скомпилируйте его.using System; using System.Globalization; using System.Threading; public class Example { public static void Main() { string[] cultureNames = { "en-GB", "en-US", "fr-FR", "ru-RU" }; Random rnd = new Random(); string cultureName = cultureNames[rnd.Next(0, cultureNames.Length)]; Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName); Console.WriteLine("The current UI culture is {0}", Thread.CurrentThread.CurrentUICulture.Name); StringLibrary strLib = new StringLibrary(); string greeting = strLib.GetGreeting(); Console.WriteLine(greeting); } }
Imports System.Globalization Imports System.Threading Module Example Public Sub Main() Dim cultureNames() As String = {"en-GB", "en-US", "fr-FR", "ru-RU"} Dim rnd As New Random() Dim cultureName As String = cultureNames(rnd.Next(0, cultureNames.Length)) Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName) Console.WriteLine("The current UI culture is {0}", Thread.CurrentThread.CurrentUICulture.Name) Dim strLib As New StringLibrary() Dim greeting As String = strLib.GetGreeting() Console.WriteLine(greeting) End Sub End Module
Чтобы скомпилировать из командной строки используйте следующую команду для компилятора C#:
csc Example.cs -r:StringLibrary.dll
Команда компилятора для Visual Basic:
vbc Example.vb -r:StringLibrary.dll
Запустите Example.exe.