我希望能够在我正在编写的.NET控制台程序中处理UTF8编码的命令行参数。不幸的是,“args”数组都传递给Main()函数,而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命令行程序还是直接从命令提示符调用.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
)已从1252代码页字节值中修改为其Unicode等价物,但发布的代码已将它们转换回正确的值(U + 2019)
不幸的是,将上述内容放入批处理文件中并不起作用......会发生完全不同的错位,产生:
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
。
但是,@ 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
命令就像我希望的那样,当我最初问这个问题的时候!
答案 0 :(得分:2)
我知道现在已经很晚了,但我也遇到了这个问题,并没有找到任何答案。我设法找到了一个解决方案,所以这就是我在参数列表中处理UTF8编码字符所做的工作:
// Handle UTF8 encoded characters
byte[] argBytes = System.Text.Encoding.Default.GetBytes( System.String.Join( " ", System.Environment.GetCommandLineArgs() ) );
string argString = System.Text.Encoding.UTF8.GetString( argBytes );
string[] args = argString.Split( ' ' );