В C, начиная с Windows Vista, вы можете запросить информацию для имени локали через GetLocaleInfoEx
. Информационные константы локали для запроса кодовых страниц ANSI и OEM, соответственно, LOCALE_IDEFAULTANSICODEPAGE
(0x1004) и LOCALE_IDEFAULTCODEPAGE
(0x000B).Вы можете перечислить все имена локалей системы с помощью EnumSystemLocalesEx
и запросить кодовые страницы ANSI и OEM для каждой локали в обратном вызове.
В скрипте Python эти функции можно вызывать с помощью ctypes .Например:
import ctypes
from ctypes import c_int
from ctypes.wintypes import BOOL, DWORD, LPVOID, LPWSTR, LPARAM, WCHAR
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
CP_ACP = 0
CP_OEMCP = 1
LOCALE_NAME_USER_DEFAULT = None
LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale"
LOCALE_RETURN_NUMBER = 0x20000000
LOCALE_IDEFAULTCODEPAGE = 0x0000000B
LOCALE_IDEFAULTANSICODEPAGE = 0x00001004
LOCALE_SENGLISHLANGUAGENAME = 0x00001001
LOCALE_SENGLISHCOUNTRYNAME = 0x00001002
LOCALE_ENUMPROCEX = ctypes.WINFUNCTYPE(BOOL,
LPWSTR, # lpLocaleString
DWORD, # dwFlags
LPARAM) # lParam
def _check_zero(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
kernel32.EnumSystemLocalesEx.errcheck = _check_zero
kernel32.EnumSystemLocalesEx.argtypes = (
LOCALE_ENUMPROCEX, # lpLocaleEnumProcEx
DWORD, # dwFlags
LPARAM, # lParam
LPVOID) # lpReserved
LCTYPE = DWORD
kernel32.GetLocaleInfoEx.errcheck = _check_zero
kernel32.GetLocaleInfoEx.argtypes = (
LPWSTR, # lpLocaleName,
LCTYPE, # LCType,
LPVOID, # lpLCData,
c_int) # cchData
def get_language(locale=LOCALE_NAME_SYSTEM_DEFAULT):
length = kernel32.GetLocaleInfoEx(locale, LOCALE_SENGLISHLANGUAGENAME,
None, 0)
language = (WCHAR * length)()
kernel32.GetLocaleInfoEx(locale, LOCALE_SENGLISHLANGUAGENAME,
language, length)
return language.value
def get_country(locale=LOCALE_NAME_SYSTEM_DEFAULT):
length = kernel32.GetLocaleInfoEx(locale, LOCALE_SENGLISHCOUNTRYNAME,
None, 0)
country = (WCHAR * length)()
kernel32.GetLocaleInfoEx(locale, LOCALE_SENGLISHCOUNTRYNAME,
country, length)
return country.value
def get_acp(locale=LOCALE_NAME_SYSTEM_DEFAULT):
cp_ansi = DWORD()
kernel32.GetLocaleInfoEx(locale, LOCALE_IDEFAULTANSICODEPAGE |
LOCALE_RETURN_NUMBER, ctypes.byref(cp_ansi),
ctypes.sizeof(cp_ansi) // ctypes.sizeof(WCHAR))
return cp_ansi.value
def get_oemcp(locale=LOCALE_NAME_SYSTEM_DEFAULT):
cp_oem = DWORD()
kernel32.GetLocaleInfoEx(locale, LOCALE_IDEFAULTCODEPAGE |
LOCALE_RETURN_NUMBER, ctypes.byref(cp_oem),
ctypes.sizeof(cp_oem) // ctypes.sizeof(WCHAR))
return cp_oem.value
def list_system_locales():
system_locales = []
@LOCALE_ENUMPROCEX
def enum_cb(locale, flags, param):
system_locales.append((locale,
get_language(locale), get_country(locale),
get_acp(locale), get_oemcp(locale)))
return True
kernel32.EnumSystemLocalesEx(enum_cb, 0, 0, None)
return sorted(system_locales)
Обратите внимание, что локали только для Unicode не имеют кодовой страницы ANSI или OEM.В этом случае возвращаемые значения относятся к текущим системным кодовым страницам ANSI и OEM, то есть CP_ACP
(0) и CP_OEMCP
(1).Например, язык хинди (hi) в Индии (IN) является языком только для Unicode:
>>> (get_acp('hi-IN'), get_oemcp('hi-IN')) == (CP_ACP, CP_OEMCP)
True