c# - visual - resgen resources to resx
¿Cómo incrustar archivos multilenguaje*.resx(o*.resources) en un solo archivo EXE? (4)
Hay muchos tutoriales sobre cómo crear archivos RESX multilingües y cómo crear ensamblajes satelitales con AL.exe, pero no he encontrado un ejemplo práctico de cómo incrustar archivos RESX / Resources / satellite-DLL en un solo archivo EXE y distribuir una aplicación multilenguaje completa como tal 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 con el nombre de cultura).
Tampoco sé cómo crear una instancia de ResourceManager para trabajar con recursos incrustados.
Mis objetivos son permitir el cambio dinámico entre un conjunto de idiomas cerrado y predefinido. Necesito una clase / método que obtenga la cadena cultural (es decir, "de-DE"), el nombre del recurso (es decir, "CancelText") y devuelva el texto traducido en función de resx / resource / dll incrustado .
Estoy usando VS2008, tenga en cuenta qué configuración de "acción de compilación" se necesita en la hoja de propiedades de los archivos de recursos / resx. Ejemplo de código de trabajo o enlace al proyecto tutorial sería lo mejor.
He utilizado el enfoque GetString
anterior. El artículo No se puede cargar un recurso de manifiesto con GetManifestResourceStream () describe cómo recuperar correctamente su recurso como un objeto de flujo. Después de eso, todo funcionó.
Mi solución: el programa solo contiene un archivo de recursos de idioma predeterminado (resx). Todos los demás idiomas se compilan desde .resx a .resources y se incorporan como 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 denominan "PIAE.LangResources.fr".
Aquí hay un código simple para recuperar la cadena traducida (debe mejorarse con los valores de almacenamiento en caché del recurso):
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);
}
No lo encontraste porque no es la forma en que funciona .NET Framework. .NET espera que las DLL de los satélites se ubiquen en una ubicación con nombre específico (por ejemplo, los directorios que llevan el nombre del idioma de los recursos que contiene, por ejemplo, de-DE
, de-DE
, chs
, ...). Si no trabajas de esa manera, .NET no podrá aplicar su magia (que consiste en elegir automáticamente el recurso correcto de acuerdo con la cultura de la interfaz de usuario actual: Thread.CurrentThread.CurrentUICulture
).
Usa este programa, funciona conmigo: EXEPack
Solo debe hacerlo manualmente cada vez que compile, sin estar seguro de si existe una herramienta de comando.