在windows容器中编码



我有一个用于文件格式转换的EXE程序。输入文件名有时包含中文或其他字符,但我在docker部署过程中遇到了一些环境编码问题。程序可以在Windows 10/11上正常运行,其中语言环境为zh-CNchcp命令显示的代码页为936

docker环境使用映像mcr.microsoft.com/windows/servercore:ltsc2022,主机环境是带有参数--isolation=process的Windows11。在容器中,使用Get-WinSystemLocale显示zh-CN,与主机相同。但是,chcp命令仍然显示437,所以我认为这是一个代码页问题。我不确定这是否正确。

我试着用英语在新安装的Windows 10上运行它,但失败了。在设置"控制面板"之后->地区->管理语言为非Unicode程序简体中文,它的工作。

更新:在测试@GChuf 2解决方案时,我发现这可能不是chcp问题。在docker中成功地将chcp更改为936后,如果myprogram.exe以汉字为输入,则无法输出正确的内容。

因此,我将问题简化了一点,并编写了一个helloworld测试程序。该程序接收可能包含中文字符的参数,然后打印出这些参数。

#include <iostream>
int main(int argc, char* argv[]) {
std::cout << argv[1] << std::endl;
return 0;
}

在Windows主机中,chcp:936Get-WinSystemLocale:zh-CN

.helloworld.exe hello // hello
.helloworld.exe 你好  // 你好

在docker中,chcp:936Get-WinSystemLocale:zh-CN

.helloworld.exe hello // hello
.helloworld.exe 你好  // ??

我发现了以下两个有用的参考链接。根据上面所说的,在my_program.exe上使用以下命令是有效的。

  1. 触摸my_program.1.mainfest文件
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
...
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">
<activeCodePage>Legacy</activeCodePage>
</asmv3:windowsSettings>
</asmv3:application>
...
</assembly>
  1. 在powershell中,执行此命令
mt.exe -manifest my_program.1.manifest -outputresource:.my_program.exe;#1
  1. my_program.exe复制到docker容器中,它运行良好

参考:

  1. 容器内部编码
  2. activeCodePage清单元素不仅可以用于将UTF-8设置为活动代码页
  3. 代码页标识符
  4. 在容器中安装Windows语言包
  5. 使用da DK文化发布服务器核心映像

我能想出两个解决这个问题的方法:

  1. 您可以在构建容器时尝试修改全局代码页设置-我不能100%确定该设置在哪里(它在注册表中-chcp不会更改全局设置)。看看这个答案,只为控制台设置代码页。当你改变"键"时,你可以试着找出哪个键被修改了;控制面板->地区->非Unicode的管理语言";通过监视注册表,或比较注册表的2个版本。

  2. 您可以尝试在调用.exe文件之前设置chcp,因为chcp只更改当前会话的代码页(如果打开另一个cmd窗口,则必须再次更改代码页)。在批处理文件中,它看起来是这样的:chcp 936 && C:your_program.exe $filepath(你必须将文件路径作为参数传递给你的批处理文件,这会使事情稍微复杂一些。也许你也可以在没有批处理文件的情况下做类似的事情。

最新更新