c# .net localization cultureinfo

c# - regasm



Manera programática de obtener todos los idiomas disponibles(en ensambles satelitales) (5)

Estoy diseñando una aplicación multilingüe usando archivos .resx.

Tengo algunos archivos como GlobalStrings.resx, GlobalStrings.es.resx, GlobalStrings.en.resx, etc. Cuando quiero usar esto, solo necesito configurar Thread.CurrentThread.CurrentCulture.

El problema: tengo un combobox con todos los idiomas disponibles, pero lo estoy cargando manualmente:

comboLanguage.Items.Add(CultureInfo.GetCultureInfo("en")); comboLanguage.Items.Add(CultureInfo.GetCultureInfo("es"));

Lo he intentado con

cmbLanguage.Items.AddRange(CultureInfo.GetCultures(CultureTypes.UserCustomCulture));

sin ningún éxito También intenté con todos los elementos en CultureTypes, pero solo estoy obteniendo una gran lista con muchos más idiomas que no estoy usando, o una lista vacía.

¿Hay alguna forma de obtener solo los idiomas compatibles?


Puede enumerar programáticamente las culturas disponibles en su aplicación

// Pass the class name of your resources as a parameter e.g. MyResources for MyResources.resx ResourceManager rm = new ResourceManager(typeof(MyResources)); CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); foreach (CultureInfo culture in cultures) { try { ResourceSet rs = rm.GetResourceSet(culture, true, false); // or ResourceSet rs = rm.GetResourceSet(new CultureInfo(culture.TwoLetterISOLanguageName), true, false); string isSupported = (rs == null) ? " is not supported" : " is supported"; Console.WriteLine(culture + isSupported); } catch (CultureNotFoundException exc) { Console.WriteLine(culture + " is not available on the machine or is an invalid culture identifier."); } }


No estoy seguro acerca de cómo obtener los idiomas, quizás pueda escanear su carpeta de instalación para archivos dll, pero establecer su idioma en un idioma no admitido no debería ser un problema.

.NET recurrirá a los recursos neutrales de cultura si no se pueden encontrar archivos específicos de cultura para que pueda seleccionar de manera segura los idiomas no admitidos.

Siempre que controle la aplicación usted mismo, puede almacenar los idiomas disponibles en algún lugar de la aplicación. Solo una cadena separada por comas con los nombres de cultura debería ser suficiente: "en, es"


Usando lo que dijo Rune Grimstad, termino con esto:

string executablePath = Path.GetDirectoryName(Application.ExecutablePath); string[] directories = Directory.GetDirectories(executablePath); foreach (string s in directories) { try { DirectoryInfo langDirectory = new DirectoryInfo(s); cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(langDirectory.Name)); } catch (Exception) { } }

o de otra manera

int pathLenght = executablePath.Length + 1; foreach (string s in directories) { try { cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(s.Remove(0, pathLenght))); } catch (Exception) { } }

Todavía no creo que esta sea una buena idea ...


Esta sería una solución basada en la siguiente declaración:
Cada conjunto de satélites para un idioma específico recibe el mismo nombre, pero se encuentra en una subcarpeta que lleva el nombre de la cultura específica, por ejemplo, fr o fr-CA.

public IEnumerable<CultureInfo> GetSupportedCulture() { //Get all culture CultureInfo[] culture = CultureInfo.GetCultures(CultureTypes.AllCultures); //Find the location where application installed. string exeLocation = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)); //Return all culture for which satellite folder found with culture code. return culture.Where(cultureInfo => Directory.Exists(Path.Combine(exeLocation, cultureInfo.Name))); }


basado en la respuesta de @ hans-holzbart pero corregido para no devolver InvariantCulture y envuelto en un método reutilizable:

public static IEnumerable<CultureInfo> GetAvailableCultures() { List<CultureInfo> result = new List<CultureInfo>(); ResourceManager rm = new ResourceManager(typeof(Resources)); CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); foreach (CultureInfo culture in cultures) { try { if (culture.Equals(CultureInfo.InvariantCulture)) continue; //do not use "==", won''t work ResourceSet rs = rm.GetResourceSet(culture, true, false); if (rs != null) result.Add(culture); } catch (CultureNotFoundException) { //NOP } } return result; }

utilizando ese método, puede obtener una lista de cadenas para agregar a algunos ComboBox con lo siguiente:

public static ObservableCollection<string> GetAvailableLanguages() { var languages = new ObservableCollection<string>(); var cultures = GetAvailableCultures(); foreach (CultureInfo culture in cultures) languages.Add(culture.NativeName + " (" + culture.EnglishName + " [" + culture.TwoLetterISOLanguageName + "])"); return languages; }