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

And*_*ykh 8 .net c# windows winforms windows-10

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

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

看起来是这样的:

在此处输入图片说明

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

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明

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

能做到吗?

Meh*_*dad 13

您可以在 ProcMon 中看到它。这似乎设定REG_SZACPMACCP以及OEMCPHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage65001

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

(实际上,我看到对一个名为的未记录函数的引用SetCPGlobal可以完成这项工作,但我在我的系统上找不到该函数。不确定它是否仍然存在。)


qew*_*jhb 9

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

我还发现吉斯勒写的解释很有帮助(来源):

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


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

  1. 赢+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"
Run Code Online (Sandbox Code Playgroud)


use*_*876 6

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

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

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

然而,看起来该复选框不仅仅做一件事。很明显,应该将“ANSI Code Page”更改为 65001,这意味着 UTF-8。看起来它也在改变字体渲染,使其更加 Unicody。

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