Short version:

用引号将参数括起来并转义\"就足够了吗?

Code version

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

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"

根据this answer,我创建了以下函数来逃避一个参数,但我可能错过了一些东西.

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

这是否足够好,或者是否有任何框架功能?

推荐答案

但比这更复杂!

我遇到了相关的问题(编写前端.exe,它将调用后端并传递所有参数+一些额外的参数),所以我查看了人们是如何做到这一点的,遇到了你的问题.起初,按照你的建议做arg.Replace (@"\", @"\\").Replace(quote, @"\"+quote)件似乎都不错.

但是,当我使用参数c:\temp a\\b调用时,这将作为c:\tempa\\b传递,这导致后端使用"c:\\temp" "a\\\\b"调用-这是不正确的,因为将有两个参数c:\\tempa\\\\b-这不是我们想要的!我们过于热衷于逃避(Windows不是Unix!)

所以我详细阅读了http://msdn.microsoft.com/en-us/library/system.environment.getcommandlineargs.aspx,它实际上描述了这些 case 是如何处理的:反斜杠被视为双引号前面的逃逸only.

这里处理\个数字的方式有一个转折点,这个解释可能会让人在一段时间内感到头晕目眩.我将try 在这里重新表述said unescape规则:假设我们有一个子串N \,后面跟着".当取消回避时,我们用int(N/2) \替换该子字符串,iff N是奇数,我们在末尾添加".

这种解码的编码是这样的:对于一个参数,找到0或\以上的每个子串,后跟",然后用\的两倍替换它,后跟\".我们可以这样做:

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

这就是全部...

附言not.等等,等等——还有更多!:)

我们正确地进行了编码,但有一个转折点,因为您将所有参数都用双引号括起来(以防其中一些参数中有空格).这里有一个边界问题——如果一个参数以\结尾,在它之后加上"将 destruct 结束引号的含义.示例c:\one\ two解析为c:\one\two,然后将其重新组合为"c:\one\" "two",这将使我(错误地)理解为一个参数c:\one" two(我try 过,我没有编造它).所以我们还需要判断参数是否以\结尾,如果是,double结尾处的反斜杠的数量,如下所示:

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

.net相关问答推荐

如何在PowerShell中隐藏任务延迟输出?

如何在dotnet中使用OpenTelemetry Prometheus导出器导出多个版本的度量?

Blazor服务器应用程序需要在页面上点击才能与元素交互

使属性只能通过绑定的 Editor(component) 编辑

在.NET C#中截断整个单词的字符串

从 byte[] 创建 zip 文件

如何从控制台应用程序中的 Task.WaitAll() 获取返回值?

maxRequestLength 的最大值?

在 Moq 中模拟泛型方法而不指定 T

重新启动(回收)应用程序池

如何右对齐 DataGridView 列中的文本?

何时使用抽象类?

如何使我的托管 NuGet 包支持 C++/CLI 项目?

仅使用 XAML 绘制纯色三角形

如何使用 Entity Framework Code First CTP 5 存储图像?

在任务中捕获异常的最佳方法是什么?

使用 LINQ 搜索树

为什么 !0 是 Microsoft 中间语言 (MSIL) 中的一种类型?

如何将 VB 项目转换为 C# 项目

如何卸载Microsoft .NET Core 1.0.0 RC2 - VS 2015 Tooling Preview 1?