如何获取每个语言环境的代码页(不仅限于我的语言环境)?
我正在寻找一个简单的Python / C# / C函数(最好是Python或C#),以便为我想要的每个语言环境找到Ansi和OEM中的代码页。
在Windows Vista及以上版本的C语言中,您可以通过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)
CP_ACP
(0)和CP_OEMCP
(1)。例如,印度(IN)的印地语(hi)是一个仅使用Unicode的语言环境:>>> (get_acp('hi-IN'), get_oemcp('hi-IN')) == (CP_ACP, CP_OEMCP)
True
list_system_locales
返回完整的国家(语言),就像我在Windows区域设置窗口中看到的那样,而不是像ff-NG
或en-MG
这样,而且这个列表对于所有Windows版本都是正确的,还是它取决于某些因素? - g319909.nwytg.coMEnumSystemLocalesEx
枚举当前系统可用的语言环境;不同的系统可能不一样。此外,枚举可以被缩小范围。我让它枚举所有语言环境,包括具有替代排序的变体。等我有时间时,我会添加一个函数来获取完整的语言和国家名称。 - Eryk SunCP_ACP
(0)。当您使用此特殊的代码页值与WideCharToMultiByte
一起使用时,它会使用系统区域设置的代码页,无论它是什么。您可以通过GetACP
进行查询。 - Eryk Sun