我有一个用于文件格式转换的EXE程序。输入文件名有时包含中文或其他字符,但我在docker部署过程中遇到了一些环境编码问题。程序可以在Windows 10/11
上正常运行,其中语言环境为zh-CN
,chcp
命令显示的代码页为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:936
、Get-WinSystemLocale:zh-CN
.helloworld.exe hello // hello
.helloworld.exe 你好 // 你好
在docker中,chcp:936
、Get-WinSystemLocale:zh-CN
.helloworld.exe hello // hello
.helloworld.exe 你好 // ??
我发现了以下两个有用的参考链接。根据上面所说的,在my_program.exe
上使用以下命令是有效的。
- 触摸
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>
- 在powershell中,执行此命令
mt.exe -manifest my_program.1.manifest -outputresource:.my_program.exe;#1
- 将
my_program.exe
复制到docker容器中,它运行良好
参考:
- 容器内部编码
- activeCodePage清单元素不仅可以用于将UTF-8设置为活动代码页
- 代码页标识符
- 在容器中安装Windows语言包
- 使用da DK文化发布服务器核心映像
我能想出两个解决这个问题的方法:
-
您可以在构建容器时尝试修改全局代码页设置-我不能100%确定该设置在哪里(它在注册表中-chcp不会更改全局设置)。看看这个答案,只为控制台设置代码页。当你改变"键"时,你可以试着找出哪个键被修改了;控制面板->地区->非Unicode的管理语言";通过监视注册表,或比较注册表的2个版本。
-
您可以尝试在调用.exe文件之前设置chcp,因为chcp只更改当前会话的代码页(如果打开另一个cmd窗口,则必须再次更改代码页)。在批处理文件中,它看起来是这样的:
chcp 936 && C:your_program.exe $filepath
(你必须将文件路径作为参数传递给你的批处理文件,这会使事情稍微复杂一些。也许你也可以在没有批处理文件的情况下做类似的事情。