powershell - 检测 Windows 系统区域设置是否使用 UTF-8 代码页的脚本?
问题描述
在最新版本的 Win10 上,可以将活动代码页 (ACP) 设置为 UTF-8 代码页。正如这里所讨论的,可以设置系统区域设置(用于在 Windows API 的“A”版本和“W”版本之间映射)以使用 UTF-8 代码页。
脚本如何检测 UTF-8 代码页是否正在使用?
正如这里和这里所讨论的,通常可以使用 WMI 来获取系统代码页 ID:
For Each os In wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem")
cs = os.CodeSet
Next
当我在 Win10 上尝试时,设置为在非 unicode 程序中使用美式英语中的“beta”utf-8 支持,WMI 继续报告代码页是 1252。即使情况显然不是这样(代码页 1252 有128 处的代码点,但 49800 处没有代码点:UTF-8 在 49800 处有代码点,128 处没有代码点)。
脚本如何检测到实际系统区域设置正在使用 UTF-8 代码页?
解决方案
PowerShell(基于 shell)解决方案:
要确定系统区域设置的(系统范围的)OEM 代码页- 这是控制台应用程序使用的代码页,请使用注册表:
# $true, if the OEM code page is set to UTF-8 (code page 65001)
'65001' -eq (Get-ItemPropertyValue HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage OEMCP)
笔记:
使用系统范围的 UTF-8 支持还会将 ANSI 代码页 (
ACP
) 设置为65001
,由旧版 GUI 应用程序使用,尤其是Windows PowerShell [1],这意味着 Windows PowerShell 的Get-Content
和Set-Content
cmdlet 的默认编码,例如,更改。从
cmd.exe
,您可以运行
reg.exe query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP
,但是您必须解析其文本输出以仅提取代码页号。请注意,遗憾的是,
Get-WinSystemLocale
在撰写本文时无法使用 PowerShell 的 cmdlet,因为[cultureinfo]
它返回的实例未反映可能存在的 UTF-8 覆盖 - 请参阅此 ServerFault 答案。
确定当前 console的活动 OEM 代码页- 这可能会或可能不会反映系统区域设置,因为可以将控制台窗口配置为使用自定义代码页,并且代码页甚至可以事先在会话中更改:
# $true, if the OEM code page is set to UTF-8 (code page 65001)
65001 -eq [Console]::OutputEncoding.CodePage
笔记:
- 从
cmd.exe
您可以执行chcp
chcp.com
,但您必须解析其文本输出以仅提取代码页号
基于 Windows API 的解决方案:
从已编译的应用程序中,您可以使用GetACP()和GetOEMCP() Windows API 函数分别查询活动的 ANSI 和 OEM 代码页。
您甚至可以从 PowerShell 中执行此操作(尽管它需要按需编译,这使得注册表解决方案成为首选):
# Compile a helper type that calls the WinAPI functions.
Add-Type -Namespace Util -Name WinApi -MemberDefinition @'
[DllImport("Kernel32.dll")]
public static extern uint GetACP();
[DllImport("Kernel32.dll")]
public static extern uint GetOEMCP();
'@
[Util.WinAPI]::GetOEMCP(), [Util.WinAPI]::GetACP()
笔记:
- 如果您编译的应用程序是一个控制台应用程序,并且您想知道相关控制台的当前 OEM 代码页- 这可能是也可能不是通过系统区域设置设置的默认页面 - 请改用该
GetConsoleOutputCP()
函数。
[1] 活动 ANSI 代码页不再与PowerShell [Core] v6+相关,后者始终将 BOM-less UTF-8 用于其 cmdlet,但在 Windows 上,活动 OEM 代码页(如 中所示)在[Console]::OutputEncoding
与外部程序。
推荐阅读
- c - 如何将 printf 的输出保存到文本文件中?
- angular - 如何在 PrimeNg 树中通过 id 查找节点?
- python - 如何编写符合 ASGI 的中间件(同时保持与框架无关)?
- python - 将两个不同的数据集彼此相邻绘制时的一个颜色条
- python - Pandas Dataframe 列名在输出中多次显示
- flutter - 如何在颤动中合并图像文件和音频文件?与 Instagram 故事中的相同
- html - 如何使用 css 更改 div 文本的字体粗细?
- android - 在 Seekbar 中使用 secondaryProgressTint 的目的是什么?
- android - Jetpack Compose:即使主题很暗,文本仍保持黑色
- javascript - 如何使用中间件组件正确导出组件?