Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

CultureInfo.GetCultures does not exist in the .NET API for Windows Store apps. How could we read all available cultures instead?

I know about the Languages list and the primary application language. I could read all languages that are available for the app that way. But I need to read all cultures (languages) that are available on the system. Previously it was easy using CultureInfo.GetCultures.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.1k views
Welcome To Ask or Share your Answers For Others

1 Answer

James' comment pointed me in the right direction. Here is the code I developed. I checked the code using a unit test to ensure that the returned neutral, specific and all cultures are identical with the cultures CultureInfo.GetCultures returns (and they indeed are :-)).

public class LocalesRetrievalException : Exception
{
    public LocalesRetrievalException(string message)
        : base(message)
    {
    }
}

public static class CultureHelper
{
    #region Windows API

    private delegate bool EnumLocalesProcExDelegate(
       [MarshalAs(UnmanagedType.LPWStr)]String lpLocaleString,
       LocaleType dwFlags, int lParam);

    [DllImport(@"kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool EnumSystemLocalesEx(EnumLocalesProcExDelegate pEnumProcEx,
       LocaleType dwFlags, int lParam, IntPtr lpReserved);

    private enum LocaleType : uint
    {
        LocaleAll = 0x00000000,             // Enumerate all named based locales
        LocaleWindows = 0x00000001,         // Shipped locales and/or replacements for them
        LocaleSupplemental = 0x00000002,    // Supplemental locales only
        LocaleAlternateSorts = 0x00000004,  // Alternate sort locales
        LocaleNeutralData = 0x00000010,     // Locales that are "neutral" (language only, region data is default)
        LocaleSpecificData = 0x00000020,    // Locales that contain language and region data
    }

    #endregion

    public enum CultureTypes : uint
    {
        SpecificCultures = LocaleType.LocaleSpecificData,
        NeutralCultures = LocaleType.LocaleNeutralData,
        AllCultures = LocaleType.LocaleWindows
    }

    public static IReadOnlyCollection<CultureInfo> GetCultures(
       CultureTypes cultureTypes)
    {
        List<CultureInfo> cultures = new List<CultureInfo>();
        EnumLocalesProcExDelegate enumCallback = (locale, flags, lParam) =>
        {
            try
            {
                cultures.Add(new CultureInfo(locale));
            }
            catch (CultureNotFoundException)
            {
                // This culture is not supported by .NET (not happened so far)
                // Must be ignored.
            }
            return true;
        };

        if (EnumSystemLocalesEx(enumCallback, (LocaleType)cultureTypes, 0,
           (IntPtr)0) == false)
        {
            int errorCode = Marshal.GetLastWin32Error();
            throw new LocalesRetrievalException("Win32 error " + errorCode +
               " while trying to get the Windows locales");
        }

        // Add the two neutral cultures that Windows misses 
        // (CultureInfo.GetCultures adds them also):
        if (cultureTypes == CultureTypes.NeutralCultures ||
           cultureTypes == CultureTypes.AllCultures)
        {
            cultures.Add(new CultureInfo("zh-CHS"));
            cultures.Add(new CultureInfo("zh-CHT"));
        }

        return new ReadOnlyCollection<CultureInfo>(cultures);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...