Получить кодовую страницу для каждой локали в OEM и Ansi - PullRequest
0 голосов
/ 04 октября 2018

Как мне получить кодовую страницу для каждой локали (не только для моей локали)?

Я искал простую функцию в python / c # / c (предпочтительнее с python или c #) для поиска для каждойлокаль, которую я хочу, что такое кодовая страница в Ansi и в OEM.

1 Ответ

0 голосов
/ 05 октября 2018

В 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
...