by Michael S. Kaplan, published on 2006/03/25 12:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/03/25/560838.aspx
Marc Brooks asked in the Suggestion Box:
In an ASP.Net 2.0 application, I want to fill a combobox (and my own internal lists) with the list of CultureInfo.
That's easy.
But how can I only include the ones whose localized resources (e.g. the correct version of the .Net runtime) has been installed?
I want my application to automatically "offer" the ones that will have localized Framework UI available.
It's funny, until I looked into Mark's question, I had no idea that there was not a way to enumerate the language resources in managed code (akin to the unmanaged EnumResourceLanguages, with the managed resource model in mind).
But after spending a little time it was clear that there was nothing like this in the System.Resources or related namespaces (that I could find, at least). The resource model clearly seems to rely on more of a "let the user choose and fall back p.r.n." mechanism than an "enumerate and choose" mechanism.
This seems mildly ironic to me given the fact that the CurrentUICulture in client apps relies on the UI language in Windows -- which is explicitly enumerated for the user, who gets to choose a language from that enumeration. :-)
But I am stubborn, so I kept digging and came up with the following:
using System;
using System.IO;
using System.Reflection;
using System.Globalization;namespace Test
{
class ResourceEnum {
[STAThread]
static void Main() {
// Grab a type that we know is in mscorlib
Type type = Type.GetType("System.Object");
Assembly assembly = Assembly.GetAssembly(type);
Console.WriteLine(assembly.CodeBase);// Enum through all the languages .NET may be localized into
foreach(CultureInfo ci in CultureInfo.GetCultures(CultureTypes.SpecificCultures | CultureTypes.NeutralCultures)) {
try {
Assembly satellite = assembly.GetSatelliteAssembly(ci);
// If we made it this far, we have the resources
Console.WriteLine("\t" + ci.Name);
}
catch(FileNotFoundException) {
// Swallow this exception, it means no such
// resources exist for the given language
}
}
}
}
}
Since I already had all of the 1.1 and 2.0 .NET language packs installed, the above code gave me a nice list:
E:\test>csc resource.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.
E:\test>resource.exe
file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
ar
zh-CHS
cs
da
de
el
es
fi
fr
he
hu
it
ja
ko
nl
no
pl
sv
tr
pt-BR
pt-PT
zh-CHT
Now the code is tied to mscorlib.dll, but it could be generalized into any assembly (by picking a different type, or using GetExecutingAssembly to get the application itself).
There are probably more clever ways to do some of this, if someone knows what they are they should point them out!
The above is my first real foray into this area, I hope I did not embarrass myself too much. :-)
Enjoy!
This post brought to you by "ጂ" (U+1302, a.k.a. ETHIOPIC SYLLABLE JI)
# Marc Brooks on 25 Mar 2006 2:51 PM:
# Michael S. Kaplan on 25 Mar 2006 3:05 PM:
# orcmid on 25 Mar 2006 4:47 PM:
# Michael S. Kaplan on 25 Mar 2006 5:04 PM:
# Marc Brooks on 27 Mar 2006 1:09 PM:
# Michael S. Kaplan on 27 Mar 2006 2:17 PM:
# Marc Brooks on 27 Mar 2006 7:13 PM:
# Marc Brooks on 27 Mar 2006 7:14 PM:
# Michael S. Kaplan on 27 Mar 2006 7:36 PM:
Craig Fisher on 30 May 2008 12:57 PM:
Very handy. Thanks!
Timur on 13 Nov 2008 4:31 AM:
Thank you very much!
referenced by
2007/01/02 Right behavior, wrong scenario
2006/12/29 By design? Well, not beautifully so....