2009-11-24 20 views
15

Hay muchos tutoriales sobre cómo crear archivos RESX multilenguaje y cómo crear ensambles satelitales con AL.exe, pero no he encontrado ejemplos de cómo incrustar archivos RESX/Resources/satellite-DLL en un único archivo EXE y distribuirlos completos aplicación multilenguaje como tal EXE.¿Cómo incrustar archivos multilenguaje * .resx (o * .resources) en un solo EXE?

Intenté usar ilmerge.exe, pero parece que no funciona para varias DLL con el mismo nombre (las DLL de satélite de cultura tienen nombres idénticos, que originalmente residen en diferentes subdirectorios denominados después de la cultura).

Tampoco sé cómo crear la instancia ResourceManager para trabajar con recursos incrustados.

Mi objetivo es habilitar la conmutación dinámica entre un conjunto de idiomas cerrado y predefinido. Necesito la clase/método que obtendrá la cadena cultural (es decir, "de-DE"), el nombre del recurso (es decir, "CancelText") y la devolución del texto traducido basado en incrustado resx/resource/dll.

Estoy usando VS2008, tenga en cuenta qué configuración para "crear acción" es necesaria en la hoja de propiedades de resx/resource files. La muestra del código de trabajo o el enlace al proyecto tutorial sería lo mejor.

+1

Sé que es escalofriante reactivar un hilo tan viejo, pero estoy interesado en saber si ha resuelto su problema y, de ser así, ¿cómo? ¿Sigue utilizando, hasta la fecha, su enfoque (la respuesta que dio a continuación)? Estoy trabajando en un proyecto similar en VS 2012 y me gustaría combinar mis DLL de recursos de idiomas en el archivo assembly/exe principal, mientras sigo usando ResourceManager para cambiar entre alemán e inglés. ¡Gracias! – Sebastian

+0

@Sebastian No exploré de ninguna otra manera, comparta si encuentra una mejor – tomash

Respuesta

8

Mi solución: el programa contiene solo un archivo de recursos de idioma predeterminado (resx). Todos los demás lenguajes se compilan desde .resx a .resources e incrustados como un archivo de recursos. ¡Importante! He cambiado la extensión porque ".resources" se reconoce como un tipo especial de recurso, por lo que mis archivos en francés se llaman "PIAE.LangResources.fr".

Aquí es código simple para recuperar cadena traducida (que debe ser mejorado con los valores de caché de recursos):

internal static string GetString(string str, string lang) 
    { 

     if (string.IsNullOrEmpty(str)) throw new ArgumentNullException("empty language query string"); 
     if (string.IsNullOrEmpty(lang)) throw new ArgumentNullException("no language resource given"); 

     // culture-specific file, i.e. "LangResources.fr" 
     Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PIAE.LangResources."+lang); 

     // resource not found, revert to default resource 
     if (null == stream) 
     {                 
      stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PIAE.Properties.LangResources.resources"); 
     } 

     ResourceReader reader = new ResourceReader(stream); 
     IDictionaryEnumerator en= reader.GetEnumerator(); 
     while (en.MoveNext()) 
     { 
      if (en.Key.Equals(str)) 
      { 
       return en.Value.ToString(); 
      } 
     } 

     // string not translated, revert to default resource 
     return LangResources.ResourceManager.GetString(str); 
    } 
+6

+1, utilizamos un enfoque similar. Duele que .net te obligue a reinventar la rueda si quieres evitar ensamblajes satelitales. Una decisión de diseño muy mala, IMO. – Heinzi

+0

Buen enfoque. –

4

No lo encontraste porque no es la forma en que funciona .NET Framework. .NET espera DLLs satelitales en una ubicación específicamente nombrada (dos directorios con el nombre del idioma de los recursos que contiene, por ejemplo, de, de-DE, chs, ...). Si no trabaja de esa manera, .NET no podrá aplicar su magia (que es elegir automáticamente el recurso correcto de acuerdo con la cultura de UI actual: Thread.CurrentThread.CurrentUICulture).

+2

Está bien para mí, puedo transmitir la cultura propia por mi cuenta, pero distribuyo una herramienta pequeña y definitivamente no quiero agregar ningún subdirector/dlls. Solo un EXE, incluso si el framework .NET aporta poca ayuda aquí. – tomash

0

uso de este programa, que funciona conmigo: EXEPack

sólo tiene que hacer manualmente cada vez que se compila, no estoy seguro si hay una herramienta de comando.

Cuestiones relacionadas