将参数用引号引起来并转义\和是否足够"?
\
"
我想string[] args使用ProcessInfo.Arguments 将命令行参数传递给另一个进程。
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"
根据这个答案,我创建了以下函数来转义单个参数,但是我可能错过了一些东西。
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)。
arg.Replace (@"\", @"\\").Replace(quote, @"\"+quote)
但是,当我使用arguments进行调用时,它将c:\temp a\\b作为c:\temp和传递a\\b,这导致使用调用后端"c:\\temp" "a\\\\b"-这是不正确的,因为将有两个参数, c:\\temp而a\\\\b-不是我们想要的!我们一直在逃逸(窗口不是unix!)。
c:\temp a\\b
c:\temp
a\\b
"c:\\temp" "a\\\\b"
c:\\temp
a\\\\b
因此,我详细阅读了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(我尝试过,但我没有做)。因此,我们还需要检查参数是否以结尾结尾\,如果是,则将结尾的反斜杠数量 加倍 ,如下所示:
c:\one\ two
c:\one\
two
"c:\one\" "two"
c:\one" two
s = "\"" + Regex.Replace(s, @"(\\+)$", @"$1$1") + "\"";