我希望能够在我正在编写的 .NET 控制台程序中处理 UTF8 编码的命令行参数。不幸的是,传递给 Main() 函数的“args”数组和 Environment 类成员(CommandLine 和 GetCommandLineArgs())都已经(错误地)转换为 Unicode,似乎将命令行视为单字节扩展-ASCII。
例如,UTF8 中的 U+2019(关闭单个撇号)为 0xe2 0x80 0x99。在 1252 密码键盘中,0x80 是欧元符号 (U+20ac),0x99 是“TM”符号 (U+2122)。(0xe2 是带抑扬符的“a”,即 U+00e2,所以不会改变)当我在命令行中传入这三个字节时,字符串的“char”元素是 0x00e2 0x20ac 和 0x2122 .
有没有办法告诉 .NET 将命令行解释为 UTF8,或者获取原始的、未处理的命令行(我可以很高兴地将其转换为 Unicode 字符串)?
更新
(遵循 dletozeun 的回答)
Windows 会做一些奇怪的事情——尤其是如果它是 XP(当我第一次问这个问题时我正在使用它)。无论您是尝试从批处理文件还是直接从命令提示符调用 .NET 命令行程序,情况似乎都不同。这可能有一个很好的理由™,但我不知道。无论如何,如果它可以帮助任何人,这就是我发现的:
命令行
打开标准命令提示符窗口并输入以下命令:
UTF8Cmd.exe abc’def
其中UTF8Cmd
是一个包含 dletozeun 解决方案的测试程序,中间字符是 0xe2、0x80、0x99(U+2019 的 UTF8 字节 - 关闭单个撇号)产生以下输出(显示 dletozeun 代码之前和之后的参数,两者都作为字符串并以十六进制转储):
Raw : "abcâ?Tdef" 61 62 63 e2 20ac 2122 64 65 66
UTF8: "abc'def" 61 62 63 2019 64 65 66
显示原始参数Raw
(
批处理文件
不幸的是,仅将上述内容放入批处理文件中是行不通的……发生了完全不同的修改,产生:
Raw : "abcÔÇÖdef" 61 62 63 d4 c7 d6 64 65 66
UTF8: "abc???def" 61 62 63 fffd fffd fffd 64 65 66
原始字节已被破坏成奇怪的东西,可能不是有效的 UTF8,因此fffd
处理后的 s 。
但是,@mvp 建议chcp 65001
先使用(然后重新设置)现在确实可以在不需要dletozeun 的代码的情况下工作:
Active code page: 65001
Raw : "abc’def" 61 62 63 2019 64 65 66
UTF8: "abc�def" 61 62 63 fffd 64 65 66
Active code page: 850
正如我在下面的评论中所指出的,我之前曾尝试过这个,但那是在一个完全失败的 XP 盒子上(它甚至似乎没有运行该命令,并使命令提示符处于一种奇怪的状态)。刚刚尝试响应答案 - 在 Windows 7 机器上 - 该chcp 65001
命令按我最初提出问题时所希望的那样工作!