How to Get the System Locale and Language Settings in Batch Script
When writing internationalized deployment scripts, installers, or logging utilities, it is often necessary to determine the language and region of the operating system. Knowing the system's locale allows your Batch Script to switch between different language packs, format dates correctly, or abort if a specific region is required.
In this guide, we will explore the different methods to retrieve the system locale, UI language, and culture codes using Batch Script, leveraging built-in Windows commands like systeminfo and wmic, as well as querying the Windows Registry.
Understanding Locales and Languages
Before writing the script, it is important to distinguish between three concepts in Windows:
- System Locale: Determines the default character set and fonts used by non-Unicode programs (e.g.,
en-us). - Input Locale / Keyboard Layout: Determines how the user types (e.g.,
0409:00000409). - UI Language: The display language used in Windows menus and dialogs (e.g.,
English (United States)or1033).
Depending on your script's goal, you may need to query one or all of these.
Method 1: Using SYSTEMINFO (The Human-Readable Approach)
The systeminfo command outputs comprehensive details about the computer, including human-readable locale strings.
@echo off
setlocal enabledelayedexpansion
echo Retrieving locales from systeminfo...
for /f "tokens=1,* delims=:" %%A in ('systeminfo') do (
echo %%A | findstr /i "Locale" >nul && (
if not defined sys_locale (
set "sys_locale=%%B"
) else (
set "input_locale=%%B"
)
)
)
:: Trim leading spaces
if defined sys_locale set "sys_locale=!sys_locale:~1!"
if defined input_locale set "input_locale=!input_locale:~1!"
echo System Locale: !sys_locale!
echo Input Locale: !input_locale!
pause
endlocal
Limitations of SYSTEMINFO
While easy to read, systeminfo is notoriously slow. It takes several seconds to gather data before piping it to findstr. Furthermore, the string "System Locale" is localized on non-English systems (e.g., "Paramètres régionaux système" in French). If you run this script on a French installation, the findstr will fail.
To build robust, internationally compatible scripts, we must use WMI or the Registry.
Method 2: Using WMI via WMIC (The Standard Method)
Windows Management Instrumentation (WMI) provides language codes that remain consistent regardless of the OS display language.
@echo off
setlocal enabledelayedexpansion
echo Retrieving OS Language Code via WMI...
:: Query WMI for the OSLanguage property
set "os_lang_code="
for /f "tokens=2 delims==" %%A in ('wmic os get OSLanguage /value 2^>nul ^| find "="') do (
set "os_lang_code=%%A"
)
:: Clean up the numeric output (wmic often adds trailing carriage returns)
if defined os_lang_code (
set /a "lang_num=os_lang_code"
) else (
echo [ERROR] Could not retrieve language code.
pause
exit /b 1
)
echo Raw OS Language Code: !lang_num!
:: Map standard language codes (LCID - Locale ID)
if "!lang_num!"=="1033" set "lang_name=English (US)"
if "!lang_num!"=="2057" set "lang_name=English (UK)"
if "!lang_num!"=="1036" set "lang_name=French (France)"
if "!lang_num!"=="1031" set "lang_name=German (Germany)"
if "!lang_num!"=="1034" set "lang_name=Spanish (Spain)"
if "!lang_num!"=="1040" set "lang_name=Italian (Italy)"
if "!lang_num!"=="1041" set "lang_name=Japanese"
if defined lang_name (
echo System Language: !lang_name!
) else (
echo System Language: Unknown LCID !lang_num!
)
pause
Why WMIC is Better
The OSLanguage property returns a Locale ID (LCID). 1033 consistently represents US English on any machine anywhere in the world. This makes wmic the preferred method for conditional logic in deployment scripts.
Microsoft provides a full reference list of LCIDs (Locale IDs) online. If you need to target a specific market, look up its numeric LCID.
Method 3: Querying the Registry (The Fastest Method)
If wmic is unavailable or you need instantaneous execution, the Windows Registry stores the current user's UI language and region formats.
@echo off
setlocal enabledelayedexpansion
echo Retrieving locales from the Registry...
:: 1. Get the Current User's preferred display language
set "ui_lang="
for /f "tokens=3" %%A in ('reg query "HKCU\Control Panel\Desktop" /v PreferredUILanguages 2^>nul ^| find "PreferredUILanguages"') do (
set "ui_lang=%%A"
)
:: 2. Get the regional formats (e.g., en-US)
set "region_format="
for /f "tokens=3" %%A in ('reg query "HKCU\Control Panel\International" /v LocaleName 2^>nul ^| find "LocaleName"') do (
set "region_format=%%A"
)
:: 3. Get the System Language Name (e.g., English)
set "sys_lang_name="
for /f "tokens=3" %%A in ('reg query "HKCU\Control Panel\International" /v sLanguage 2^>nul ^| find "sLanguage"') do (
set "sys_lang_name=%%A"
)
echo UI Language: !ui_lang!
echo Region Format: !region_format!
echo Sys Language: !sys_lang_name!
pause
The Power of LocaleName
The LocaleName registry value typically returns an IETF language tag (like en-US, fr-FR, es-MX). This is arguably the most modern and widely recognized format for handling languages across different programming environments.
Practical Example: A Language-Aware Batch Script
Here is an example of using the registry method to display localized messages to the user.
@echo off
setlocal enabledelayedexpansion
:: Default to English
set "msg_welcome=Welcome to the setup program."
set "msg_error=An error occurred."
:: Determine the user's locale
set "locale="
for /f "tokens=3" %%A in ('reg query "HKCU\Control Panel\International" /v LocaleName 2^>nul ^| find "LocaleName"') do (
set "locale=%%A"
)
if defined locale (
:: Extract just the two-letter language code (e.g., 'es' from 'es-MX')
set "lang_code=!locale:~0,2!"
:: Override messages based on language
if /i "!lang_code!"=="fr" (
set "msg_welcome=Bienvenue dans le programme d'installation."
set "msg_error=Une erreur s'est produite."
)
if /i "!lang_code!"=="es" (
set "msg_welcome=Bienvenido al programa de instalacion."
set "msg_error=Ocurrio un error."
)
if /i "!lang_code!"=="it" (
set "msg_welcome=Benvenuti nel programma di installazione."
set "msg_error=Si e' verificato un errore."
)
)
:: Output the localized result
echo !msg_welcome!
pause
Common Mistakes
The Wrong Way: Parsing SYSTEMINFO on Unknown Machines
:: WRONG - Fails on non-English operating systems
systeminfo | find "System Locale"
Output Concern:
If you deploy this script internationally, find "System Locale" will return nothing because the label translates to local languages. By the time the script evaluates the string, it fails.
The Correct Way: Use Registry or WMI
Always use wmic for LCID strings or reg query for LocaleName strings. These values represent the configuration standard and do not translate their keys.
Best Practices
- Prefer
LocaleNamein the Registry: Retrieving tags likeen-USvia the registry is incredibly fast and highly compatible with web standards and modern software API formats. - Extract the Base Language: If
LocaleNamereturnses-AR(Spanish - Argentina), but you only have basic Spanish translations, use!locale:~0,2!to extract justes. This allows your script to support generic language groups cleanly. - Provide a Fallback: Always declare your variables in English at the top of the script. If the WMI or Registry query fails, or the language is unsupported, the script will gracefully default to English.
Conclusion
Getting the system locale and language settings in Batch Script prevents unexpected errors when formatting dates, paths, or logging outputs on international machines. While systeminfo provides a readable summary, using wmic to retrieve the numerical LCID or querying the registry for the LocaleName string provides the speed, reliability, and precision required for professional script development.