“测试版:将Unicode UTF-8用于全球语言支持”实际上是做什么的?

时间:2019-06-02 23:11:11

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

在某些Windows 10版本中(从2018年4月开始,内部使用,也称为“正常” 1903年),有一个名为“ Beta:使用Unicode UTF-8进行全球语言支持”的新选项。

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

这是它的样子:

enter image description here

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

在Visual Studio 2019中创建一个全新的Windows Froms应用程序。在主窗体上,指定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);
}

运行程序,如果未选中此复选框,将显示以下内容:

enter image description here

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

enter image description here

您可以在Wikipedia上查找Webdings字体。根据给定的字符表,这两个字符的代码为"\U0001F5D5\U0001F5D9"。如果我使用它们而不是"0r",则 with 复选框已选中,但 without 复选框已选中,现在看起来像这样:

enter image description here

我想找到一个始终有效的解决方案,无论该复选框处于选中状态还是未选中状态,该解决方案都是无偿的。

可以做到吗?

3 个答案:

答案 0 :(得分:2)

您可以在ProcMon中看到它。 似乎在REG_SZ中设置了ACPMACCPOEMCP的值HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage  到65001

我不确定,但是可能gAnsiCodePage读取的KernelBase.dll中的变量GetACP有关。如果您真的想,则可以 动态地为您的程序更改它,而无需考虑系统设置如何通过动态反汇编GetACP来查找指令序列读取gAnsiCodePage并获取指向它的指针,然后直接更新该变量。

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

答案 1 :(得分:2)

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

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

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

但是,看起来该复选框所做的不只是一件事情。很明显,应该将“ ANSI代码页”更改为65001,这表示UTF-8。看起来它也在改变字体渲染,使其更像Unicody。

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

答案 2 :(得分:1)

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

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

<块引用>

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


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

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

或者通过 reg 文件:

Windows Registry Editor Version 5.00

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