2010-03-06 5 views
5

Comment puis-je échapper une chaîne inconnue pour passer à Process.Start en tant qu'argument?Chaîne d'échappement pour Process.Start

J'échappe actuellement aux guillemets et aux barres obliques inversées de base, mais récemment, mon entrée a commencé à contenir des éléments comme http://www.fileformat.info/info/unicode/char/ff02/index.htm (guillemet pleine largeur).

Donc, ma question est, tout ce que j'ai besoin d'échapper à passer une chaîne en toute sécurité comme un argument pour Process.Start?

Editer: Je dois donc clarifier cela. Ce que je cherche vraiment, c'est une liste de tous les caractères qui doivent être échappés dans une chaîne entre guillemets ("foo") pour cmd.exe. À l'origine, je traitais le caractère de guillemets doubles ainsi que le caractère de barre oblique inverse, mais j'ai finalement eu une entrée qui contenait un guillemet de pleine largeur (comme référencé ci-dessus) qui devait également être échappé. Donc la question est, quoi d'autre ai-je besoin d'échapper pour un argument de chaîne entre guillemets passé à cmd.exe avec Process.Start?

+0

Vous pourriez être intéressé par le [MedallionShell] (https://github.com/madelson/MedallionShell) bibliothèque, qui gère automatiquement les arguments de processus d'échappement et concaténation – ChaseMedallion

Répondre

6

Cela peut être utile:

  • arguments En premier lieu, plusieurs sont normalement séparés les uns des autres par des espaces . Dans la figure 2.3, la commande a trois arguments, c: *. Bak, e: \ backup, et/s. Parfois, d'autres caractères sont utilisés comme séparateurs d'arguments. Par exemple, la commande COPY peut utiliser les caractères + pour séparer plusieurs noms de fichiers . Deuxièmement, tout argument qui contient des espaces ou qui commence ou se termine par des espaces doit être placé entre guillemets. Ceci est particulièrement important lorsque utilise des noms de fichiers et de répertoires longs, qui contiennent fréquemment un ou plusieurs espaces . Si un argument entre guillemets contient lui-même un guillemet double , le guillemet double doit être doublé. Par exemple, entrez "Cité" Argument comme "" "Cité" "Argument". Troisièmement, les commutateurs de commande commencent toujours par une barre oblique/un caractère. Un commutateur est un argument qui modifie l'opération de la commande de manière . De temps en temps, les commutateurs commencent par un caractère + ou -. Certains commutateurs sont globaux et affectent la commande indépendamment de leur position dans la liste d'arguments . Les autres commutateurs sont local et affectent des arguments spécifiques (tel que celui précédant immédiatement le commutateur ).

  • Quatrièmement, tous les caractères de shell réservés qui ne sont pas entre guillemets doivent être être échappés. Ces caractères ont une signification particulière pour l'interpréteur de commandes Windows NT .La coquille réservée caractères sont:

    & |() <>^

Pour passer des caractères shell réservés comme partie d'un argument pour une commande, soit l'argument entier doit être entre guillemets, ou le caractère réservé doit être échappé. Préfixe un caractère réservé avec un caractère carat (^) pour l'échapper. Pour exemple, la commande exemple suivant ne fonctionne pas comme prévu, parce que < et> sont des caractères shell réservés:

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> 

En règle générale, les caractères shell réservés ne sont pas utilisés dans les commandes, donc les collisions qui nécessitent l'utilisation de échappe est rare. Ils se produisent, cependant. Par exemple, le populaire programme PKZIP prend en charge un commutateur - & pour basculer vers . Pour utiliser ce commutateur correctement sous Windows NT, -^& doit être tapé.

Astuce: Le caractère carat est lui-même un caractère de coquille réservé. Ainsi, à tapez un caractère carat dans le cadre d'un argument de commande , tapez deux carats à la place. L'échappement est nécessaire seulement lorsque l'interprétation de la coquille normale des caractères réservés doit être contournée.

  • Enfin, la longueur maximale autorisée de une commande shell semble être non documentée par Microsoft. Un test simple montre que l'interpréteur de commandes Windows NT autorise des commandes très longues, supérieures à 4 000 caractères. En pratique, il n'y a pas de limite supérieure significative à la longueur d'une commande.

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

+0

Cela aide un peu, mais ce que je cherche vraiment est: quand dans une chaîne entre guillemets, tout ce qui doit être échappé dans les citations. – thelsdj

+0

Autant que je sache: il suffit d'échapper le guillemet fullwidth dans les guillemets fullwidth (en les doublant). La quatrième étape de l'article mentionne les caractères réservés "NOT in double quotes", je suppose que vous pouvez utiliser les caractères entre guillemets. Et je n'utiliserais pas de caractères non-ASCII. – Zyphrax

+0

Il semble que les barres obliques inverses devraient également être échappées en doublant. Si deux sont utilisés dans une rangée, ils sont interprétés comme un; doubler semble donner un comportement cohérent. – jtpereyda

1

This answer est le plus proche que je l'ai vu à expliquer la folie des arguments de ligne de commande Windows. Ce n'est pas aussi simple que ça en a l'air.

Vous ne devriez pas avoir besoin d'échapper à U + FF02 en général. Le problème est que si vous finissez par passer ce caractère à une ligne de commande qui ne supporte pas Unicode, il sera réduit à son équivalent non-compatible, la citation ASCII, à quel point il devient dangereux. Si votre commande va à un outil qui ne supporte pas Unicode, vous devez le replier en ASCII avant en appliquant l'argument d'échappement, plutôt que de laisser l'outil à l'autre extrémité le faire. (Généralement, le problème sera lorsque cet outil utilisera C stdlib pour lire ses arguments .Ceci est défini en termes de char 8 bits, l'implémentation de Windows stdlib utilise la page de code système par défaut ("ANSI") pour coder la chaîne à 8 bits, et cette page de codes n'est jamais un format de transformation Unicode, donc vous perdrez toujours des caractères.)

0

Ma tentative d'échapper:

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() + '"'; 
    } 
0

Ceci est un exemple de la façon dont une citation peut être présent dans une chaîne de recherche google:

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

La première ligne de la question spécifie que l'OP souhaite "échapper à une ** chaîne ** inconnue". Votre méthode fournie ne peut pas être utilisée pour une telle chaîne. – Spooky

Questions connexes