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

6

3

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?

Mcmahan answered 14/9, 2017 at 7:13 Comment(4)
RegionInfo.CurrentRegion. Time to upgrade your Google-Fu.Abampere
There exists an "Administrative" tab in the Region Control Panel[Win32], not the Modern Settings one. Click on "Copy Settings" & "Change System Locale". Probably might solve your quastionLandpoor
I finally found the answer to my question in this thread: #8879759Mcmahan
@SamAxe: I did try RegionInfo.CurrentRegion. It returned Denmark (DNK), as shown in my original post.Mcmahan
M
6

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
}
Mcmahan answered 14/9, 2017 at 7:59 Comment(2)
Can you show me what did you pass to GetMachineCurrentLocation(?) and what did you get from calling GetMachineCurrentLocation() method?Cambium
In my case : var test = RegionAndLanguageHelper.GetMachineCurrentLocation(RegionInfo.CurrentRegion.GeoId); => test is "" (empty)Cambium
C
3

Read msdn documentation: RegionInfo Properties

var regionInfo = RegionInfo.CurrentRegion;
var name = regionInfo.Name;
var englishName = regionInfo.EnglishName;
var displayName = regionInfo.DisplayName;

Console.WriteLine("Name: {0}", name);
Console.WriteLine("EnglishName: {0}", englishName);
Console.WriteLine("DisplayName: {0}", displayName);   

Name: DE
EnglishName: Germany
DisplayName: Germany

Cambium answered 14/9, 2017 at 7:36 Comment(7)
I tried that, as indicated in my original post. It did not help. CurrentThread.CurrentCulture did not change when I changed my country in "Region & language settings".Mcmahan
@ClausAppel Did you try with var regionInfo = RegionInfo.CurrentRegion;? working for me.Cambium
@ClausAppel, from msdn: "The RegionInfo class does not automatically detect changes in the system settings, but the CurrentRegion property is updated when you call the ClearCachedData method".Tai
Yes, I tried with RegionInfo.CurrentRegion. I showed that in my original post. Which CultureInfo object do I need to call ClearCachedData on in order to refresh RegionInfo.CurrentRegion? I tried some ClearCachedData calls in my original code, and they did not help.Mcmahan
@ClausAppel, I tried this answer code on my PC (win10, germany is selected as country) and strangely enough it shows en-US. So there is indeed a problem somewhere.Tai
This also does not work for me. I can change my "Country or Region" in the Windows 10 UI to anything and I get always UK related data. Is there no native .Net way to do this?Natant
The agnostic option is the ISO-3166 code: RegionInfo.CurrentRegion.TwoLetterISORegionName, which is what you'll need if you're working with GoogleMapsMarrilee
N
0

Much shorter than the chosen answer and without a need for DllImports or ClearCachedData:

var regKeyGeoId = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Control Panel\International\Geo");
var geoID = (string)regKeyGeoId.GetValue("Nation");
var allRegions = CultureInfo.GetCultures(CultureTypes.SpecificCultures).Select(x => new RegionInfo(x.ToString()));
var regionInfo = allRegions.FirstOrDefault(r => r.GeoId == Int32.Parse(geoID));
Console.WriteLine("EnglishName:" + regionInfo.EnglishName);
Console.WriteLine("DisplayName:" + regionInfo.DisplayName);
Console.WriteLine("NativeName:" + regionInfo.NativeName);
Console.WriteLine("ISOCurrencySymbol:" + regionInfo.ISOCurrencySymbol);
Console.WriteLine("Name:" + regionInfo.Name);

This reads the information you have set in Windows 10 under "Regional & Language" > "Country or region".

Credit should go to @Zan as mine is just an extension of his post: Get Current Location (as specified in Region and Language) in C#

Natant answered 29/12, 2018 at 18:40 Comment(0)
M
0

If you are working with GoogleMaps, it's he ISO-3166 RegionInfo.CurrentRegion.TwoLetterISORegionName

Marrilee answered 11/2, 2024 at 18:32 Comment(0)
H
0

Based on above solution, I hope the following code would be helpful for C++ developers to get the country name in Windows:

std::string GetCurrentCountryShortName()
{
    // Get the region of user
    // Refer: https://learn.microsoft.com/en-us/windows/win32/intl/table-of-geographical-locations
    GEOID geo_id = GetUserGeoID(SYSGEOCLASS::GEOCLASS_NATION);
    if (geo_id == GEOID_NOT_AVAILABLE)
    {
        std::cout << "GetUserGeoID failed because user does not set geographical location" << std::endl;;
        return "";
    }

    LCID lcid = ::GetUserDefaultLCID();

    int buffer_size = ::GetGeoInfoA(geo_id, SYSGEOTYPE::GEO_ISO2, nullptr, 0, lcid);
    if (buffer_size == 0)
    {
        std::cout << "Create buffer for GetGeoInfoA failed with error: " << ::GetLastError() << std::endl;
        return "";
    }

    auto buffer = std::make_unique<CHAR[]>(buffer_size);
    ZeroMemory(buffer.get(), buffer_size);
    if (!::GetGeoInfoA(geo_id, SYSGEOTYPE::GEO_ISO2, buffer.get(), buffer_size, lcid))
    {
        std::cout << "GetGeoInfoA failed with error: " << ::GetLastError() << std::endl;
        return "";
    }

    std::string country_name = buffer.get();
    return country_name;
}

In addition, you could change SYSGEOTYPE::GEO_ISO2 to achieve your intention.

Heteropterous answered 16/5, 2024 at 3:55 Comment(0)
H
-1

Try

    var geographicRegion = new Windows.Globalization.GeographicRegion();
    var code = geographicRegion.CodeTwoLetter;

or

    var region = Windows.System.UserProfile.GlobalizationPreferences.HomeGeographicRegion;
Harbird answered 14/9, 2017 at 8:1 Comment(1)
This is UWP solution.Tai

© 2022 - 2025 — McMap. All rights reserved.