C#: programmatically get and set non-unicode languages for windows OS

28 Aug

We know that we can use English version of Windows and at the same time to display non-unicode texts such as Chinese and Japanese etc. The procedures are as follows:

Control Panel > Region > Administrative Tab, and then “Change system locale” button.



But how do this using C#? This post offers my initial attempt to accomplish this task.

The settings for this non-unicode languages are kept in registry:


The value for the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Language “default” value is the hex code (LCID Hexadecimal) of the system’s non-unicode language, for commonly used LCID code, click here or this link from Microsoft for details.

For instance, “0804” is the hex LCID code for “Chinese – People’s Republic of China”.

To get or change the non-unicode languages for windows OS, we can edit this registry key value using C#, and the code snippet is like this:


Similarly, the code to set a specific language is then straightforward:


But wait, this is not all! If you calling the function:


you will find there is no error, no exception, and using regedit.exe shows the registry key is also changed correctly, but, if you using control panel region settings to have a look, you will find this is NOT updated. The reason is, you have to restart to make this setting take effect!

So, I created another function to restart the computer in code:


Great! Now call the RestartComputer() after calling SetSystemNonUnicodeLanguage(), it worked.

To save your effort, I have created a C# class SystemNonUnicodeLanguageEntry with static methods as below. Download this class here.image


Posted by on August 28, 2013 in Dotnet/C#, Programming, Windows


Tags: , , , , , , , ,

3 responses to “C#: programmatically get and set non-unicode languages for windows OS

  1. Georg

    March 24, 2014 at 5:09 pm

    Nice, but not 100% correct…
    If changing the language for non-unicode programs, the registry is modified instantly…
    And your solution will return the new value. But this new value will take effect not until a reboot!
    If you want to get the current set language for non-unicode programs you have to parse the output of “systeminfo”…

    private static CultureInfo GetSystemNonUnicodeLanguageFromSysteminfo()
    Process p = new Process();
    p.StartInfo = new ProcessStartInfo(“systeminfo”);
    string stdOut;
    string stdErr;
    p.Run(out stdOut, out stdErr);//extension method which redirects stdout and stderr

    string languageName = ParseSystemLocale(stdOut);
    return CultureInfo.GetCultureInfo(languageName);

    private static string ParseSystemLocale(string systemInfoStdOut)
    //find for example “System Locale: en-US;English (United States)”
    const string toSearch = “System Locale:”;
    string systemLocaleLine = systemInfoStdOut.GetLineContainingString(toSearch);//extension method to find the first line, which contains our string
    systemLocaleLine = systemLocaleLine.Substring(toSearch.Length).Trim();
    systemLocaleLine = systemLocaleLine.Split(‘;’).First();

    return systemLocaleLine;

  2. xinyustudio

    March 24, 2014 at 11:27 pm

    Cool. Thanks for the input!

  3. Amol Kanthe

    January 5, 2018 at 5:58 pm

    Thanks for the information. it is very useful.
    Can you post a final code which does not require reboot (after incorporating George’s suggestions).


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: