2

我希望能够在我正在编写的 .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命令按我最初提出问题时所希望的那样工作!

4

1 回答 1

3

我知道已经很晚了,但我也刚遇到这个问题,在任何地方都没有找到任何答案。我设法找到了一个解决方案,所以这是我在处理参数列表中的 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( ' ' );
于 2014-12-10T10:32:55.853 回答