Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

c# - Replacement for CultureInfo.GetCultures in .NET Windows Store apps

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...