Проблемы основной сборки и сборки спутников при выборке ресурсов XAML и RESX в C # .Net - PullRequest
6 голосов
/ 10 декабря 2011

В локализованной программе, содержащей нейтральный для культуры файл XAML, некоторые значки, нейтральные для культуры, и локализованные строки, как вы организуете эти различные типы ресурсов, чтобы их можно было найти?Независимо от того, какое расположение я пробую, я нахожу, что один из моих типов ресурсов недоступен.

У меня проблема в следующем:

  • Файл MainWindow.xamlвсегда встраивается в спутниковую сборку в США.Если для UltimateResourceFallbackLocation задано значение MainAssembly, он никогда не найдет BAML окна, и я получаю исключение в вызове InitializeComponent ().Поэтому я вынужден установить для UltimateResourceFallbackLocation значение «Satellite».

  • Культурно-нейтральные ресурсы значков, содержащиеся в файле Resources.resx, всегда встроены в основную сборку EXE и не могут быть найдены, если UltimateResourceFallbackLocationустановлен на спутник.Это может показаться полностью несовместимым с требованиями файла MainWindow.xaml.

  • Если я полностью удаляю UICulture и NeutralResourcesLanguage, что заставляет данные XAML и RESX встраиваться вMainAssembly, то мои специфичные для культуры строки не работают.

Вопрос: что я делаю не так?Как я должен построить проект так, чтобы все эти три типа ресурсов были доступны.

Редактировать (рабочее решение, но оно кажется неправильным):

Мне удалосьчтобы заставить мой нейтральный к культуре файл RESX, Resources.resx, встроить в сборку Satellite, полностью продублировав его, переименовав дубликат Resources.en-US.resx и установив для Resources.resx значение Build Action: None (поэтому только Resources.resxиспользуется для создания файла Resources.Designer.cs, но больше не вставляет данные в сборку Main EXE).

Программа теперь работает для всех трех случаев (локализованные строки, нелокализованные данные из resx инелокализованные данные из XAML), поскольку все мои нейтральные к культуре ресурсы теперь находятся в сборке en-US, но дублирование файла Resources.resx для достижения этой цели кажется довольно глупым.

Это глупо?Есть ли более разумный способ сделать это?

Ответы [ 2 ]

3 голосов
/ 10 июля 2014

Локализация с WPF очень хлопотна из-за плохой документации. Я потратил часы на некоторые идеи.

Файл MainWindow.xaml всегда встроен в спутниковую сборку en-US. Если для UltimateResourceFallbackLocation задано значение MainAssembly, он никогда не найдет BAML окна, и я получаю исключение в вызове InitializeComponent (). Поэтому я вынужден установить UltimateResourceFallbackLocation в «Спутник».

Это связано с тем, что ваш файл project.vcproj, вероятно, содержит <UICulture>en-US</UICulture>. Это, по сути, говорит VS генерировать стеллитовые сборки (вы видите, что папка en-US создается с соответствующим спутником в ней).

UltimateResourceFallbackLocation.MainAssembly теперь говорит .net ускорить поиск информации о локализации, используя встроенную вместо соответствующей в каталоге. Если ваша системная культура - en-US, это прекрасно объяснит это поведение.

цитирование Ким Гамильтон :

... тогда ResourceManager ищет ресурсы «en-US» непосредственно в основной сборке, вместо поиска сначала в папке «en-US». Поскольку ресурсные зонды могут быть дорогими, этот атрибут может помочь улучшить производительность.

Поскольку вы нашли решение для своей второй точки, осталось только одно:

Если я полностью удаляю UICulture и NeutralResourcesLanguage - что заставляет данные XAML и RESX оба встраиваться в MainAssembly, то мои специфичные для культуры строки не работают.

На самом деле WPF все еще выполняет локализацию: если у вас нет записи типа <UICulture>en-US</UICulture> в файле .vcproj, wpf все еще пытается найти спутник в каталоге, имя которого соответствует System.Threading.Thread.CurrentThread.CurrentUICulture. Если оно найдено, оно используется. За исключением, конечно, если ваш нейтральный язык установлен на язык вашей системы, и вы используете стратегию восстановления основной сборки. Чтобы проверить локализацию в вашей системе en-US, вы должны выбрать другую культуру, например, ja-JP как нейтральный язык. Затем предоставьте папку en-US с соответствующим спутником.

Итак, что я использую для локализации и рекомендую:

  1. не имеют <UICulture>en-US</UICulture> в файле .vcproj
  2. использовать [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
  3. предоставить все каталоги целевой культуры с соответствующими спутниками.
2 голосов
/ 05 апреля 2012

Я считаю, что произвольной «более разумной» альтернативой является использование Assembly Linker (Al.exe) для компиляции файлов .resources в спутниковые сборки, как описано в этой статье .

** Обновление **

Примеры, использованные в этой статье:

Эта команда Assembly Linker (Al.exe) создает вспомогательную сборку для приложения MyApp из файла strings.de.resources.

al /t:lib /embed:strings.de.resources /culture:de /out:MyApp.resources.dll

Эта команда Assembly Linker (Al.exe) также создает вспомогательную сборку для приложения MyApp из файла strings.de.resources. Опция /template заставляет вспомогательную сборку наследовать метаданные сборки от родительской сборки MyApp.dll.

al /t:lib /embed:strings.de.resources /culture:de /out:MyApp.resources.dll
/template:MyApp.dll
...