Search code examples
c#localecultureregioncountry

In C#, how to get the "Country or region" selected under "Region & language" in Windows 10?


I am running Windows 10. When I open "Region & language settings" from the start menu, I can select a "Country or region". I am trying to get this value in a C# program.

I am in Denmark. I have tried changing my country to Germany (see screenshot), but I cannot get my code to return Germany. Rebooting the computer did not help.

I have written some code inspired by this thread.

My code looks like this (trying various things at once, getting all the region/culture things I can think of):

private static void Main(string[] args)
{
    Thread.CurrentThread.CurrentCulture.ClearCachedData();
    Thread.CurrentThread.CurrentUICulture.ClearCachedData();
    var thread = new Thread(() => ((Action) (() =>
    {
        Console.WriteLine("Current culture: {0}", Thread.CurrentThread.CurrentCulture.Name);
        Console.WriteLine("Current UI culture: {0}", Thread.CurrentThread.CurrentUICulture.Name);
        Console.WriteLine("Installed UI culture: {0}", CultureInfo.InstalledUICulture.Name);
        Console.WriteLine("Current region: {0}", RegionInfo.CurrentRegion.ThreeLetterISORegionName);
        Console.WriteLine("System default LCID: {0}", GetSystemDefaultLCID());
    }))());
    thread.Start();
    thread.Join();
    Console.ReadKey();
}

[DllImport("kernel32.dll")]
private static extern uint GetSystemDefaultLCID();

It outputs:

Current culture: en-DK
Current UI culture: en-US
Installed UI culture: en-US
Current region: DNK
System default LCID: 1033

How can I get my program to detect that I have selected Germany? What method or property do I need to call? And what restarts or cache-clearing might be necessary?


Solution

  • I found the answer to my question in this thread.

    I am using the below code, as proposed by @SanjaySingh in that thread and only slightly modified.

    If I call GetMachineCurrentLocation with the geoFriendlyname parameter set to 5, I get the three-letter ISO region code I want (for Germany this is "DEU").

    The values for geoFriendlyname can be found here.

    public static class RegionAndLanguageHelper
    {
        #region Constants
    
        private const int GEO_FRIENDLYNAME = 8;
    
        #endregion
    
        #region Private Enums
    
        private enum GeoClass : int
        {
            Nation = 16,
            Region = 14,
        };
    
        #endregion
    
        #region Win32 Declarations
    
        [DllImport("kernel32.dll", ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int GetUserGeoID(GeoClass geoClass);
    
        [DllImport("kernel32.dll")]
        private static extern int GetUserDefaultLCID();
    
        [DllImport("kernel32.dll")]
        private static extern int GetGeoInfo(int geoid, int geoType, StringBuilder lpGeoData, int cchData, int langid);
    
        #endregion
    
        #region Public Methods
    
        /// <summary>
        /// Returns machine current location as specified in Region and Language settings.
        /// </summary>
        /// <param name="geoFriendlyname"></param>
        public static string GetMachineCurrentLocation(int geoFriendlyname)
        {
            int geoId = GetUserGeoID(GeoClass.Nation); ;
            int lcid = GetUserDefaultLCID();
            StringBuilder locationBuffer = new StringBuilder(100);
            GetGeoInfo(geoId, geoFriendlyname, locationBuffer, locationBuffer.Capacity, lcid);
    
            return locationBuffer.ToString().Trim();
        }
    
        #endregion
    }