Process.Start的转义字符串

如何转义未知字符串以传递给Process.Start作为参数?

我目前正在逃避基本的引号和反斜杠,但最近我的输入已经开始包含诸如http://www.fileformat.info/info/unicode/char/ff02/index.htm (全宽引号)之类的内容。

所以我的问题是,我需要逃避什么才能安全地传递一个字符串作为Process.Start的参数?

编辑:所以我需要澄清一下。 我真正需要的是一个必须在cmd.exe的带引号的字符串(“foo”)中转义的所有字符的列表。 我最初处理双引号字符以及反斜杠字符,但我最后有一些输入包含一个全宽带引号(如上所述),它也需要转义。 所以问题是,对于使用Process.Start传递给cmd.exe的带引号的字符串参数,我还需要转义什么?

这可能很有用:

  • 首先,多个参数通常通过空格彼此分开。 在图2.3中,该命令有三个参数:c:*。bak,e:\ backup和/ s。 有时,其他字符用作参数分隔符。 例如,COPY命令可以使用+字符分隔多个文件名。

  • 其次,任何包含空格或以空格开头或结尾的参数必须用双引号括起来。 在使用通常包含一个或多个空格的长文件和目录名时,这一点尤为重要。 如果双引号参数本身包含双引号字符,则双引号必须加倍。 例如,输入“Quoted”Argument as“”“Quoted”“Argument”。

  • 第三,命令开关总是以斜杠/字符开头。 switch是以某种方式修改命令操作的参数。 偶尔,开关以+或 – 字符开头。 某些开关是全局的,无论它们在参数列表中的位置如何,都会影响命令。 其他交换机是本地的,会影​​响特定的参数(例如交换机前面的参数)。

  • 第四,必须转义所有不在双引号中的保留shell字符。 这些字符对Windows NT命令shell具有特殊含义。 保留的shell字符是:

    &| ()<> ^

要将保留的shell字符作为命令参数的一部分传递,要么必须将整个参数括在双引号中,要么必须转义保留字符。 使用克拉(^)字符作为保留字符的前缀以使其脱离。 例如,以下命令示例将无法按预期工作,因为<和>是保留的shell字符:

1. C:\>echo  2. The syntax of the command is incorrect. Instead, escape the two reserved characters, as follows: 1. C:\>echo ^ 2.  

通常,保留的shell字符不会在命令中使用,因此很少需要使用转义的冲突。 然而,他们确实发生了。 例如,流行的PKZIP程序支持 – &切换以启用磁盘跨越。 要在Windows NT下正确使用此开关,必须键入 – ^&。

提示 :克拉字符本身就是一个保留的shell字符。 因此,要键入一个克拉字符作为命令参数的一部分,请键入两个克拉。 只有在必须绕过保留字符的正常shell解释时才需要转义。

  • 最后,Microsoft命令的最大允许长度似乎没有记录。 简单的测试表明,Windows NT命令shell允许超长的命令 – 超过4,000个字符。 实际上,命令的长度没有明显的上限。

http://technet.microsoft.com/en-us/library/cc723564.aspx

这个答案是我见过的最接近解释Windows命令行参数疯狂的答案 。 它并不像最初看起来那么简单。

一般来说,你不应该逃避U + FF02。 问题是,如果你最终将该字符传递给不支持Unicode的命令行,它将被解决为其不兼容的等价物,ASCII引用,此时它变得危险。 如果您的命令是使用不支持Unicode的工具,则应应用参数转义之前将其折叠为ASCII,而不是让另一端的工具执行此操作。

(通常,问题是当该工具使用C stdlib读取其参数时。这是根据8位char定义的; Windows stdlib实现使用默认(“ANSI”)系统代码页将字符串编码为8 -bit,该代码页永远不是Unicode转换格式,因此您将永远丢失字符。)

我试图逃跑:

  public static string QuoteArgument(string arg) { // The inverse of http://msdn.microsoft.com/en-us/library/system.environment.getcommandlineargs.aspx // Suppose we wish to get after unquoting: \\share\"some folder"\ // We should provide: "\\share\\\"some folder\"\\" // Escape quotes ==> \\share\\\"some folder\"\ // For quotes with N preceding backslashes, replace with 2k+1 preceding backslashes. var res = new StringBuilder(); // For sequences of backslashes before quotes: // odd ==> 2x+1, even => 2x ==> "\\share\\\"some folder" var numBackslashes = 0; for (var i = 0; i < arg.Length; ++i) { if(arg[i] == '"') { res.Append('\\', 2 * numBackslashes + 1); res.Append('"'); numBackslashes = 0; } else if(arg[i] == '\\') { numBackslashes++; } else { res.Append('\\', numBackslashes); res.Append(arg[i]); numBackslashes = 0; } } res.Append('\\', numBackslashes); // Enquote, doubling last sequence of backslashes ==> "\\share\\\"some folder\"\\" var numTrailingBackslashes = 0; for (var i = res.Length - 1; i > 0; --i) { if (res[i] != '\\') { numTrailingBackslashes = res.Length - 1 - i; break; } } res.Append('\\', numTrailingBackslashes); return '"' + res.ToString() + '"'; } 

这是一个如何在Google搜索字符串中显示引号的示例:

 string link = @"https://www.google.com/search?q=\""Hello+World!\"""; Process.Start("CHROME.EXE", link);