如何将未知字符串转义为传递给Process.Start作为参数?
我目前正在转义基本引号和反斜杠,但最近我的输入开始包含http://www.fileformat.info/info/unicode/char/ff02/index.htm(全宽引号)等内容。
所以我的问题是,为了安全地传递一个字符串作为Process.Start的参数,我需要逃避什么?
修改 所以我需要澄清一下。我真正想要的是一个必须在cmd.exe的带引号的字符串(“foo”)中转义的所有字符的列表。我最初处理双引号字符以及反斜杠字符,但我最终有一些输入包含一个全宽带引号(如上所述),它也需要转义。所以问题是,对于使用Process.Start传递给cmd.exe的带引号的字符串参数,我还需要转义什么?
答案 0 :(得分:6)
这可能有用:
首先,多个参数通常彼此分开 空间。在图2.3中,命令有 三个参数,c:*。bak,e:\ backup, 和/ s。偶尔,其他人物 用作参数分隔符。对于 例如,COPY命令可以使用+ 字符分隔多个 文件名。
其次,任何包含空格或以空格开头或结尾的参数 必须用双引号括起来。 这一点尤为重要 使用长文件和目录名称, 通常包含一个或多个 空间。如果是双引号参数 本身包含双引号 字符,双引号必须 一倍。例如,输入“Quoted” 争论为“”“引用”“论据”。
第三,命令开关总是以斜杠/字符开头。一个 switch是一个修改的参数 一些命令的操作 办法。偶尔,交换机开始 a +或 - 字符。有些开关是 全局,并影响命令 不管他们在哪个位置 参数列表。其他开关是 本地的,并影响具体的论点 (例如紧接在前面的那个 开关)。
第四,所有保留的shell字符都不是双引号 逃脱。这些人物有 Windows NT的特殊含义 命令shell。保留的shell 字符是:
&安培; | ()< > ^
将保留的shell字符作为传递 命令参数的一部分, 要么整个论点必须是 用双引号括起来,或者用 保留字符必须转义。 使用a作为保留字符的前缀 克拉(^)字符逃脱它。对于 例如,以下命令示例 将不会按预期工作,因为< 和>是保留的shell字符:
1. C:\>echo <dir> 2. The syntax of the command is incorrect. Instead, escape the two reserved characters, as follows: 1. C:\>echo ^<dir^> 2. <dir>
通常,保留shell 字符不在命令中使用, 所以需要使用的碰撞 逃跑是罕见的。他们确实发生了, 然而。例如,流行 PKZIP计划支持 - &amp;切换到 启用磁盘跨越。要用这个 在Windows NT下正确切换, - ^&amp; 必须输入。
提示:克拉字符本身就是一个保留的shell字符。因此,到 键入一个克拉字符作为一部分 命令参数,键入两克拉 代替。逃生只是必要的 当正常的shell解释 保留字符必须是 绕过。
- 最后,允许的最大长度为 shell命令似乎是 没有由Microsoft记录。简单 测试显示Windows NT 命令shell允许很长时间 命令 - 超过4,000 字符。实际上, 没有明显的上限 命令的长度。
答案 1 :(得分:1)
This answer是我见过最接近解释Windows命令行参数疯狂的。它并不像最初看起来那么简单。
您通常不需要逃离U + FF02。问题是,如果你最终将该字符传递给不支持Unicode的命令行,它将被解决为与其不兼容的等价物,ASCII引用,此时它变得危险。如果您的命令是使用不支持Unicode的工具,则应在应用参数转义之前将其折叠为ASCII ,而不是让另一端的工具执行此操作。
(通常,问题是当该工具使用C stdlib读取其参数时。这是根据8位char
定义的; Windows stdlib实现使用默认(“ANSI”)系统用于将字符串编码为8位的代码页,该代码页永远不是Unicode转换格式,因此您将始终丢失字符。)
答案 2 :(得分:0)
我试图逃跑:
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() + '"';
}
答案 3 :(得分:0)
这是一个如何在Google搜索字符串中显示引号的示例:
string link = @"https://www.google.com/search?q=\""Hello+World!\""";
Process.Start("CHROME.EXE", link);