【问题标题】:Does Process.StartInfo.Arguments support a UTF-8 string?Process.StartInfo.Arguments 是否支持 UTF-8 字符串?
【发布时间】:2010-04-13 08:03:08
【问题描述】:

您可以使用 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 支持还是不支持?

【问题讨论】:

    标签: c# utf-8


    【解决方案1】:

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

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

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

    一些背景信息:使用“窄”(系统代码页)入口点(例如 main(int argc, char** argv))而不是“宽”(UTF-16)入口点 wmain(int argc, wchar_t** argv) 的 C 或 C++ 程序被称为通过将命令行转换为系统代码页的存根 - 不能是 UTF-8。

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

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

    Caveat Coder:如果这在您或其他人的机器上出现严重错误,请不要感到惊讶,这取决于当前系统代码页中每个可能的字节是否有效,系统代码页与您的程序启动时没有不同,您正在运行的程序不使用任何编码依赖的 Windows 函数(带有 A、W 后缀的版本)的数据,等等。

    【讨论】:

    • 是的,我可以看到程序以 unicode 接收它们的命令行,但我不知道 Process 类的 StartInfo.Arguments 是否可以将值传播到 unicode 中的应用程序。在我的测试中似乎没有。
    • @Patrick:确切地说,当程序启动时,它从 Windows 接收到的原始值始终是 Unicode。根据它的编写方式,它可能会在看到它之前将其转换为系统代码页。
    • 如果您使用 main 作为入口点,您仍然可以使用 GetCommandLine (msdn.microsoft.com/en-us/library/ms683156(VS.85).aspx) 获取 UTF-16 参数。这就是 Qt 的 QCoreApplication 在 Windows 上的工作方式。
    【解决方案2】:

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

    如果这不是日语代码页,则该翻译会产生问号,因为日语字形只有日语代码页中的代码。非日语使用者通常不太希望切换系统代码页。 Utf8 肯定行不通,程序不会指望它们。考虑在虚拟机中运行此程序。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 您是通过使用 Process 和 ProcessStartInfo 启动应用程序还是直接从命令行将参数传递给您的应用程序?
      • 我使用了 Process / ProcessStartInfo - 我只将“cmd.exe”更改为“test.exe”,这是我的 WinForms 应用程序。
      【解决方案4】:

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

      看看here

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

      【讨论】:

      • 我知道字符串支持 unicode - 我只是不确定 ProcessStartInfo 上的 Arguments 属性是否正确地将其传播到正在执行的应用程序。好像没有。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多