一尘不染

C#中的转义命令行参数

c#

简洁版本:

将参数用引号引起来并转义\和是否足够"

代码版本

我想string[] args使用ProcessInfo.Arguments 将命令行参数传递给另一个进程。

ProcessStartInfo info = new ProcessStartInfo();
info.FileName = Application.ExecutablePath;
info.UseShellExecute = true;
info.Verb = "runas"; // Provides Run as Administrator
info.Arguments = EscapeCommandLineArguments(args);
Process.Start(info);

问题是我将参数作为数组获取,必须将它们合并为单个字符串。可以设计一个参数来欺骗我的程序。

my.exe "C:\Documents and Settings\MyPath \" --kill-all-humans \" except fry"

根据这个答案,我创建了以下函数来转义单个参数,但是我可能错过了一些东西。

private static string EscapeCommandLineArguments(string[] args)
{
    string arguments = "";
    foreach (string arg in args)
    {
        arguments += " \"" +
            arg.Replace ("\\", "\\\\").Replace("\"", "\\\"") +
            "\"";
    }
    return arguments;
}

这足够好还是有任何框架功能呢?


阅读 424

收藏
2020-05-19

共1个答案

一尘不染

比这还复杂!

我遇到了相关的问题(编写前端.exe,它将调用传递所有参数的后端+一些额外的参数),因此我查看了人们是如何做到的,遇到了您的问题。最初,按照您的建议,一切似乎都很好arg.Replace (@"\", @"\\").Replace(quote, @"\"+quote)

但是,当我使用arguments进行调用时,它将c:\temp a\\b作为c:\temp和传递a\\b,这导致使用调用后端"c:\\temp" "a\\\\b"-这是不正确的,因为将有两个参数,
c:\\tempa\\\\b-不是我们想要的!我们一直在逃逸(窗口不是unix!)。

因此,我详细阅读了http://msdn.microsoft.com/zh-
cn/library/system.environment.getcommandlineargs.aspx,它实际上描述了如何处理这些情况:反斜杠
在double前面被视为转义引用。

在这里如何\处理多个存在一个扭曲,说明可能会使您头昏眼花一会儿。在这里,我将尝试重新表述所说的不转义规则:说我们有一个 N
的子字符串\,然后是"。进行转义时,我们用 int(N / 2) 替换该子字符串,\并且如果 N
为奇数,则"在末尾添加。

这样的解码的编码将是这样的:对于一个参数,找到0或更大的每个子串,\后跟,"然后用两次多次替换它\,然后是\"。我们可以这样做:

s = Regex.Replace(arg, @"(\\*)" + "\"", @"$1$1\" + "\"");

就这样…

PS。… 不是 。等等,等等-还有更多!:)

我们正确地进行了编码,但是有一个扭曲,因为您将所有参数都括在双引号中(以防某些参数中有空格)。有一个边界问题-
万一参数以结尾\,在该参数"后面添加会破坏右引号的含义。c:\one\ two解析为示例c:\one\two然后将其重新组合为"c:\one\" "two"我(误)理解为一个参数c:\one" two(我尝试过,但我没有做)。因此,我们还需要检查参数是否以结尾结尾\,如果是,则将结尾的反斜杠数量 加倍 ,如下所示:

s = "\"" + Regex.Replace(s, @"(\\+)$", @"$1$1") + "\"";
2020-05-19