Enumerating available localized language resources in .NET

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:

You ROCK!  That's so simple I'm embarrassed that I didn't find it.

Thanks,
 Marc

# Michael S. Kaplan on 25 Mar 2006 3:05 PM:

No need to be embarrassed, Marc. I'm actually a little embarrassed that I spelled your name wrong! :-)

We're all trying to figure how to do stuff -- and this particular feature ought to be built in. We need to save our "cleverness" for the real hard stuff, not things that should just work....

# orcmid on 25 Mar 2006 4:47 PM:

So, like, well, I'm sure I don't know what is happening here, and I will treasure all of your code, but uh, golly, where are en and ru and such?

# Michael S. Kaplan on 25 Mar 2006 5:04 PM:

Hi Dennis!

Ah, the RU lack was because I did not have that one installed! I just installed it now and it is on the list.


As for EN, that is not on the list because there is no "EN" language pack. If you try to install one you get the message at this link: http://download.microsoft.com/download/b/6/7/b675c24f-5c1c-458f-a5f4-e34bbaf099cf/readme.htm which says:

Microsoft .NET Framework Redistributable Package Version 2.0

There is no language pack for the English version of this redistributable package. If you wish to install the language pack for a different language, please return to the Microsoft Download Center page where you found this download and select a different language.

# Marc Brooks on 27 Mar 2006 1:09 PM:

While where talking about embarassment and the downloads for the language pack... how bogus is it that you can't read the download page  or installation information (like the EULA I'm implicitly agreeing to) when downloading a different language pack?  How is it that nobody at MS thinks this is silly (e.g. the "display language" != the pack language to be installed).

See my rant here:
http://musingmarc.blogspot.com/2006/01/somebody-needs-to-understand-page.html

# Michael S. Kaplan on 27 Mar 2006 2:17 PM:

Hmmm.... actually I have no problems with this approach -- it falls under the theory of "if you can't read it, then why the hell are you clicking on it!!!"

# Marc Brooks on 27 Mar 2006 7:13 PM:

I've posted my further adventures on my blog.

# Marc Brooks on 27 Mar 2006 7:14 PM:

So how am I, as a WebServer administrator supposed to install these language packs?

# Michael S. Kaplan on 27 Mar 2006 7:36 PM:

Hmmm... they are all downloadable files (though they did not have the foresight to give them different names, you'll have to do THAT part!).

Just install them on the web server like you would any update....

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....

go to newer or older post, or back to index or month or day