【问题标题】:What does "Beta: Use Unicode UTF-8 for worldwide language support" actually do?“测试版:使用 Unicode UTF-8 支持全球语言”实际上有什么作用?
【发布时间】:2019-06-02 23:11:11
【问题描述】:

在某些 Windows 10 版本(从 2018 年 4 月开始的内部人员以及“正常”1903 年)中,有一个名为“测试版:使用 Unicode UTF-8 获得全球语言支持”的新选项。

您可以通过转到设置来查看此选项,然后: 所有设置 -> 时间和语言 -> 语言 -> “管理语言设置”

这就是它的样子:

选中此复选框时,我观察到一些异常情况(如下),我想知道此复选框的具体作用以及为什么会发生以下情况

在您的 Visual Studio 2019 中创建一个全新的 Windows 窗体应用程序。在主窗体上指定 Paint 偶数处理程序,如下所示:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Font buttonFont = new Font("Webdings", 9.25f);
    TextRenderer.DrawText(e.Graphics, "0r", buttonFont, new Point(), Color.Black);
}

运行程序,如果未选中复选框,您将看到以下内容:

但是,如果您选中复选框(并按要求重新启动),则会更改为:

您可以在维基百科上查找Webdings 字体。根据给出的字符表,这两个字符的代码是"\U0001F5D5\U0001F5D9"。如果我使用它们而不是 "0r" 它可以工作 with 选中的复选框但 没有 选中的复选框现在看起来像这样:

我想找到一个始终有效的解决方案,无论复选框是否选中。

这个可以吗?

【问题讨论】:

  • 系统区域设置决定了 ANSI 和 OEM 代码页。该复选框强制它们使用 UTF-8(代码页 65001)。显然,这有一个次要影响,导致DrawText 不使用所选字体呈现“0r”。我猜这是因为 Webdings 和 Wingding 等符号字体在字体的 OS/2 表中没有声明任何 Unicode 范围或旧代码页。相反,它们将代码映射到任意字形。继续猜测,如果您选择常规字体,"\U0001F5D5\U0001F5D9" 可能会起作用。显然字体后备可以找到所需的字体。
  • 除了前两句话,我只是猜测。你比我更接近问题及其解决方案。如果您不介意,我希望您自己回答。
  • 你的源代码是什么编码的?更改 Windows 设置将更改 CP_ACP,这将更改文本文件中没有显式编码(通过 BOM)的字符的解释。您的来源似乎包含扩展字符。在源代码中,我建议在字符串文字中对任何非 ASCII 字符使用 unicode 转义码,否则您将取决于环境设置,这些设置可能会有所不同(在这种情况下会有所不同)。
  • @PaulDempsey 复制它的所有信息都在问题中给出。没有进行 OP 中未提及的特殊编码更改。此外,我的源代码似乎不包含字符串文字中的 unicode 转义码以外的扩展字符,这些字符在 OP 中被标记为这样。

标签: c# .net windows winforms windows-10


【解决方案1】:

您可以在 ProcMon 中看到它。 似乎在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage 中设置了REG_SZACPMACCPOEMCP65001

我不完全确定,但它可能KernelBase.dll 中的变量gAnsiCodePage 相关,GetACP 读取该变量。如果您真的想要,您可能可以通过动态反汇编GetACP 以找到读取@ 的指令序列,为您的程序动态更改它,而不管系统设置如何987654333@并获取指向它的指针,然后直接更新变量。

(实际上,我 see references to an undocumented function named SetCPGlobal 可以完成这项工作,但我在我的系统上找不到该功能。不确定它是否仍然存在。)

【讨论】:

  • 谢谢,如果勾选了 UTF-8,'ACPT'、'MACCP' 和 'OEMCP' 的值确实会变为 65001。您是如何首先发现这些是由 UTF-8 复选框修改的注册表值?
  • @JoakimThorén:你可以在ProcMon看到它?
【解决方案2】:

大多数 Windows C API 有两种不同的变体:

  • “A”变体使用 8 位字符串,无论系统配置的编码是什么。这取决于配置的国家/语言。 (微软将配置的编码称为“ANSI 代码页”,但实际上与 ANSI 无关)。
  • “W”变体以固定的几乎 UTF-16 编码使用 16 位字符串。 (“几乎”是因为允许“未配对的代理”;如果您不知道它们是什么,请不要担心它们)。

Microsoft 官方建议不要使用“A”版本,而是确保您的代码始终使用“W”变体。这样,无论用户的国家/语言配置如何,您都应该获得一致的行为。

但是,该复选框看起来不止一件事。很明显,它应该将“ANSI 代码页”更改为 65001,这意味着 UTF-8。看起来它也在将字体渲染更改为更加统一。

我建议你检测GetACP() == 65001,然后绘制你的字符串的Unicode版本,否则绘制旧的“0r”版本。我不确定你是如何从 .NET 中做到这一点的......

【讨论】:

  • “A”变体适用于 ANSI C、C89 和 C90。 “W”变体不适用于 ANSI C,并且在 C95 标准被广泛采用之前与可移植 ('ANSI') C 不兼容。
  • @david:我说的是特定于 Windows 的 API,例如 CreateFileA / CreateFileW。它们完全独立于您使用的语言,无论是 C、C++、Pascal 或其他任何版本的某些版本。您说的是微软对官方 C 规范提出的更改,以添加更好的宽字符支持,这是另一回事(并且是 C 运行时的一部分,而不是核心 OS API)。
  • 我在评论您的断言,即 ANSI API(可与 ANSI c 一起使用)与 ANSI 无关。
  • docs.microsoft.com/en-us/windows/win32/intl/code-pages解释了“A”后缀的由来:“Windows代码页,俗称“ANSI代码页”,是[encodings]……原来,Windows代码页1252,代码通常用于英语和其他西欧语言的页面,基于美国国家标准协会 (ANSI) 草案。...但 Windows 代码页 1252 是在标准成为最终版本之前实施的,并且不完全相同... “A”版本处理基于 Windows 代码页的文本”。
  • 即后缀是“A”,因为 Windows 支持一堆 8 位编码,微软常用的是基于 ANSI 草稿代码页,但其他大多数与 ANSI 无关。所以整个编码机制被西方程序员错误地称为“ANSI代码页”,这个名字就被卡住了。这与 ANSI C 无关。
【解决方案3】:

请看这个问题,看看启用后解决了什么问题:How to save to file non-ascii output of program in Powershell?

我还发现 Ghisler 写的解释很有帮助 (source):

如果您选中此选项,Windows 将使用代码页 65001(Unicode UTF-8) 而不是像 1252 (Western Latin1) 这样的本地代码页 所有纯文本文件。优点是在例如创建的文本文件。 俄语语言环境也可以在其他语言环境中读取,例如西方或 欧洲中部。缺点是 ANSI-Only 程序(最老的 程序)将显示垃圾而不是重音字符。


我在这里留下了两种启用它的方法,我认为它们会对许多用户有所帮助:

  1. Win+R -> intl.cpl
  2. Administrative标签
  3. 点击Change system locale按钮。
  4. 启用Beta: Use Unicode UTF-8 for worldwide language support
  5. 重启

或者通过reg文件:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"ACP"="65001"
"OEMCP"="65001"
"MACCP"="65001"

【讨论】:

  • 不错;还值得一提的是需要重新启动(如果您通过控制面板执行此操作,系统会提示您)。请注意,该设置适用于 OEM 代码页(在 console 应用程序中使用;例如,美国英语系统上的 437 (CP437))和 i>ANSI 代码页(在 GUI 子系统应用程序中使用;例如,1252 (Windows-1252)。使用这种仍处于测试阶段的设置具有深远的影响,因此可能并不适合所有人- 见this answer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 2013-02-06
  • 2014-10-04
  • 2019-07-10
  • 2012-07-03
  • 2015-12-02
相关资源
最近更新 更多