2011-12-10 17 views
5

En un programa localizado que contiene un archivo XAML culturalmente neutro, algunos iconos de cultura neutral y cadenas localizadas, ¿cómo se organizan estos diferentes tipos de recursos para que puedan todo se encuentra? No importa qué arreglo intente, encuentro que uno de mis tipos de recursos es inaccesible.Conjunto principal frente a los problemas de ensamblaje de satélite cuando se obtienen recursos XAML y RESX en C# .Net

El problema que estoy teniendo es:

  • archivo La MainWindow.xaml siempre se basa en el conjunto de satélites en-US. Si UltimateResourceFallbackLocation se establece en MainAssembly, nunca encontrará el BAML de la ventana y recibo una excepción en la llamada InitializeComponent(). Por lo tanto, me siento obligado a establecer UltimateResourceFallbackLocation en "Satélite".

  • Los recursos de icono cultural neutro contenidos en el archivo Resources.resx siempre se compilan en el ensamblado EXE principal y no se pueden encontrar si UltimateResourceFallbackLocation está establecido en Satellite. Esto parece ser totalmente incompatible con los requisitos del archivo MainWindow.xaml.

  • Si elimino por completo UICulture y NeutralResourcesLanguage, lo que obliga a los datos XAML y RESX a integrarse en el MainAssembly, entonces las cadenas específicas de mi cultura no funcionan.

La pregunta es: ¿qué estoy haciendo mal? ¿Cómo se supone que debo construir el proyecto para que estos tres tipos de recursos sean accesibles?

Editar (solución de trabajo pero parece mal):

He conseguido que mi cultura resx neutra, Resources.resx, para construir en el conjunto del satélite mediante la duplicación por completo, cambiar el nombre de los recursos duplicados .en-US.resx y estableciendo Resources.resx para Build Action: None (para que Resources.resx solo se use para generar el archivo Resources.Designer.cs pero ya no inserte datos en el ensamblado Main EXE).

El programa ahora funciona para los tres casos (cadenas localizadas, datos no localizados de resx y datos no localizados de XAML) ya que todos mis recursos culturales neutrales están ahora en el ensamblado en-US, pero duplicando los Recursos El archivo .resx para lograr esto parece bastante tonto.

¿Es tonto? ¿Hay alguna forma más inteligente de hacer esto?

Respuesta

2

Creo que una alternativa arbitraria "más inteligente" es usar el Ensamblador (Al.exe) para compilar archivos .resources en ensamblajes satelitales como se describe en este article.

** ** Actualizar

ejemplos utilizados en ese artículo:

Este Assembly Linker (al.exe) comando crea un ensamblado satélite para la aplicación de los MiApl strings.de.resources de archivos .

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

Este comando Assembly Linker (al.exe) también crea un ensamblado satélite para la aplicación de los MiApl strings.de.resources de archivo. La opción /template hace que el ensamblaje satélite herede los metadatos del conjunto principal MyApp.dll.

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

Tu respuesta fue fundamental para ayudarme a encontrar una solución a un problema similar: http://www.mathewweaver.com/2013/11/internalgetsatelliteassembly-finding.html – mweaver

+0

Me alegro de ser de ayuda :) – chridam

2

La localización con WPF es muy problemática debido a la mala documentación. Pasé horas para algunas ideas.

El archivo MainWindow.xaml siempre se integra en el conjunto satélite en-US. Si UltimateResourceFallbackLocation se establece en MainAssembly, nunca encontrará el BAML de la ventana y recibo una excepción en la llamada InitializeComponent(). Por lo tanto, me siento obligado a establecer UltimateResourceFallbackLocation en "Satélite".

Esto se debe a que su archivo project.vcproj probablemente contiene <UICulture>en-US</UICulture>. Esto esencialmente le dice a VS que genere ensamblajes de estelita (verá que la carpeta en-US se está creando con el satélite correspondiente en ella).

UltimateResourceFallbackLocation.MainAssembly ahora le dice a .net que acelere la búsqueda de la información de localización utilizando la integrada en lugar de la que está en el directorio correspondiente. Si su cultura de sistemas es en-US, explicaría este comportamiento a la perfección.

quoting Kim Hamilton:

... entonces el ResourceManager se buscan recursos "en-us" directamente en el conjunto principal, en lugar de buscar por primera vez en una carpeta “en-US”. Dado que las pruebas de recursos pueden ser costosas, este atributo puede ayudar a mejorar el rendimiento.

Desde que ha encontrado una solución para su segundo bulletpoint sólo hay una izquierda:

Si quito el UICulture y NeutralResourcesLanguage por completo - lo que obliga a los datos XAML y RESX a construir tanto en el MainAssembly, mis cadenas específicas de cultura no funcionan.

En realidad WPF aún lo hace la localización: Cuando usted no tiene una entrada como <UICulture>en-US</UICulture> en el archivo .vcproj WPF sigue tratando de encontrar un satélite en un directorio que tiene el mismo nombre que a System.Threading.Thread.CurrentThread.CurrentUICulture. Se encuentra, se está utilizando. Excepto, por supuesto, si su idioma neutral está configurado en el idioma de su sistema y utiliza la estrategia de repliegue del conjunto principal. Para que pueda probar la localización en su sistema en-US debe elegir alguna otra cultura, p. ja-JP como el idioma neutral. Luego proporcione la carpeta en-US con el satélite correspondiente en ella.

Así que lo que estoy utilizando para la localización y recomiendo es:

  1. no tiene <UICulture>en-US</UICulture> en el archivo .vcproj
  2. uso [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
  3. proporcionan todos los directorios de destino de la cultura con los satélites a juego.
Cuestiones relacionadas