Process.StartInfo.Arguments是否支持UTF-8字符串?

你可以使用UTF-8字符串作为StartInfo的参数吗?

我试图将UTF-8(在本例中为日语字符串)作为控制台参数传递给应用程序。

像这样的东西(这只是一个例子!(cmd.exe将是一个自定义应用程序))

var process = new System.Diagnostics.Process(); process.StartInfo.Arguments = "/K \"echo これはテストです\""; process.StartInfo.FileName = "cmd.exe"; process.StartInfo.UseShellExecute = true; process.Start(); process.WaitForExit(); 

执行此操作似乎松开了UTF-8字符串,所有目标应用程序看到的都是“echo ?????????”

直接在命令行上执行此命令(通过粘贴参数),目标应用程序正确接收字符串,即使命令行本身似乎没有正确显示它。

我是否需要做一些特殊的事情才能在参数中启用UTF-8支持,或者这是不支持的?

这完全取决于您尝试启动的程序。 Process类完全支持Unicode,操作系统也是如此。 但程序可能很旧并且使用8位字符。 它将使用GetCommandLineA()来检索命令行参数,本机Unicode GetCommandLineW()API函数的ANSI版本。 并且使用控制面板+区域和语言选项,非Unicode程序的语言中配置的系统默认代码页将Unicode字符串转换为8位字符。 WideCharToMultiByte()使用CP_ACP。

如果那不是日语代码页,那么该翻译会产生问号,因为日语字形只在日语代码页中有代码。 对于非日语的人来说,通常不希望切换系统代码页。 Utf8当然不会起作用,该程序不会指望它们。 考虑在虚拟机中运行此程序。

程序以UTF-16接收命令行,与.NET字符串的编码相同:

 Arguments = "/U /K \"echo これはテストです> output.txt\""; 

控制台窗口无法显示当前代码页/所选字体之外的字符。 但是,我假设你不想调用echo,所以这完全取决于你所调用的程序是如何编写的。

一些背景信息:使用’narrow’(系统代码页)入口点的C或C ++程序,例如main(int argc, char** argv) ,而不是’wide’(UTF-16)入口点, wmain(int argc, wchar_t** argv)由存根调用,该存根将命令行转换为系统代码页 – 不能是UTF-8。

到目前为止,最好的选择是更改程序以使用宽入口点,并且只需获得与.NET字符串中相同的UTF-16。 如果这是不可能的,那么你可以尝试的一个技巧是传递一个UTF-16命令行,当转换为系统代码页时,它是UTF-8用于你想要它使用的字符:

 Arguments = Encoding.Default.GetString(Encoding.UTF8.GetBytes(args)); 

Caveat Coder:如果在你或他人的机器上出现可怕的错误,请不要感到惊讶,这取决于当前系统代码页中每个可能的字节是否有效,系统代码页与程序启动时没有区别,程序你正在运行不使用任何编码依赖Windowsfunction的数据(具有A,W后缀版本的那些),依此类推。

我刚刚创建了一个Windows窗体应用程序,它在RichTextBox中显示Environment.CommandLine,并且字符串显示正确,因此可以通过这种方式传递Unicode字符串。

我认为我的操作系统默认使用代码页1252,因此即使在粘贴参数时也无法在命令提示符中显示这些字符。

使用的字符串[ System.String或plain string ]是基于Unicode的。 所以,是的,他们可以维持上述编码。

看看这里

您需要检查与操作系统相关的设置(代码页,语言等)