Process.Start的转义字符串

时间:2010-03-06 17:26:53

标签: c# cmd escaping

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

我目前正在转义基本引号和反斜杠,但最近我的输入开始包含http://www.fileformat.info/info/unicode/char/ff02/index.htm(全宽引号)等内容。

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

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

4 个答案:

答案 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   字符。实际上,   没有明显的上限   命令的长度。
  •   

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

答案 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);