如何获取每个语言环境的代码页(不仅限于我的语言环境)?
我正在python / c#/ c(更喜欢python或c#)中寻找一个简单的函数,以便为每个语言环境找到我想要的Ansi和OEM中的代码页。
答案 0 :(得分:1)
在C中,从Windows Vista开始,您可以通过locale name查询GetLocaleInfoEx
的信息。用于查询ANSI和OEM代码页的locale information constants分别是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)。例如,印度(IN)的北印度语(hi)语言是仅Unicode的语言环境:
>>> (get_acp('hi-IN'), get_oemcp('hi-IN')) == (CP_ACP, CP_OEMCP)
True