2010-03-06 13 views
5

¿Cómo puedo escapar de una cadena desconocida para pasar a Process.Start como argumento?Cadena de escape para Process.Start

Actualmente, escapo de las comillas básicas y de las barras diagonales inversas, pero recientemente mi entrada ha comenzado a contener cosas como http://www.fileformat.info/info/unicode/char/ff02/index.htm (comillas de ancho completo).

Así que mi pregunta es, ¿qué necesito para escapar para pasar con seguridad una cadena como argumento para Process.Start?

Edit: Así que tengo que aclarar esto. Lo que realmente estoy buscando es una lista de todos los caracteres que deben escaparse en una cadena entrecomillada ("foo") para cmd.exe. Originalmente me ocupé del carácter de comillas dobles y de la barra inclinada invertida, pero finalmente tuve una entrada que contenía una comilla de ancho completo (como se mencionó anteriormente) que también debía escaparse. Entonces, la pregunta es, ¿qué más debo evitar para un argumento de cadena entrecomillado pasado a cmd.exe con Process.Start?

+0

usted puede estar interesado en el [MedallionShell] (https://github.com/madelson/MedallionShell) biblioteca, que maneja automáticamente los argumentos de proceso de escape y concatenación – ChaseMedallion

Respuesta

6

Esto podría ser útil:

  • En primer lugar, varios argumentos están normalmente separadas una de otra por espacios. En la Figura 2.3, el comando tiene tres argumentos, c: *. Bak, e: \ backup, y/s. Ocasionalmente, se usan otros caracteres como separadores de argumentos. Para el ejemplo , el comando COPY puede usar los caracteres + para separar múltiples nombres de archivo .

  • En segundo lugar, cualquier argumento que contenga espacios o comience o termine con espacios debe estar entre comillas dobles. Esto es particularmente importante cuando utiliza nombres largos de archivos y directorios, que frecuentemente contienen uno o más espacios . Si un argumento de doble cita contiene un carácter de comillas dobles , la comilla doble debe ser duplicada. Por ejemplo, ingrese "Citado" Argumento como "" "Citado" "Argumento".

  • En tercer lugar, los interruptores de comando siempre comienzan con una barra/carácter. Un modificador es un argumento que modifica el funcionamiento del comando en alguna forma . Ocasionalmente, los conmutadores comienzan con a + o - carácter. Algunos conmutadores son global, y afectan al comando independientemente de su posición en la lista de argumentos . Otros conmutadores son local, y afectan a los argumentos específicos (como el que precede inmediatamente al del conmutador).

  • En cuarto lugar, se deben escapar todos los caracteres de shell reservados que no estén entre comillas dobles . Estos caracteres tienen significado especial para el shell de comandos de Windows NT .Los caracteres de shell reservados son:

    & |() <>^

Para pasar de concha caracteres reservados como parte de un argumento a favor de un comando, ya sea todo el argumento debe ser entre comillas dobles, o la carácter reservado debe ser escapado. Prefija un carácter reservado con un carácter de quilates (^) para escapar de él. Para ejemplo, el siguiente ejemplo de comando no funcionará como se esperaba, debido a < y> son caracteres reservados 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> 

Por lo general, la cáscara reservada caracteres no se utilizan en los comandos, así colisiones que requieren el uso de escapes es raro. Sí ocurren, sin embargo. Por ejemplo, el popular programa PKZIP admite un - & cambiar a habilitar la expansión del disco. Para usar este interruptor correctamente en Windows NT, se debe escribir -^& .

Consejo: El carácter de quilates es en sí mismo un carácter de shell reservado. Por lo tanto, a escriba un carácter de quilates como parte de un argumento de comando , escriba dos quilates en su lugar. Solo es necesario escapar cuando la interpretación de shell normal de caracteres reservados debe ser anulada.

  • Por último, la longitud máxima permitida de comando una cáscara parece ser indocumentado por Microsoft. Las pruebas simples de muestran que el shell de comandos de Windows NT permite comandos muy largos : más de 4,000 caracteres. En términos prácticos, no hay un límite superior significativo para la longitud de un comando.

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

+0

Esto ayuda un poco, pero lo que realmente estoy buscando es: cuando en una cadena citada, todo lo que necesita ser escapado dentro de las citas – thelsdj

+0

Por lo que puedo decir: solo tiene que escapar de la comilla de ancho completo dentro de las comillas de ancho completo (al doblarlas). El paso cuatro del artículo menciona caracteres reservados "NO entre comillas dobles", supongo que PUEDE usar los caracteres dentro de las comillas dobles. Y no usaría caracteres que no sean ASCII. – Zyphrax

+0

Parece que las barras diagonales inversas también deben evitarse duplicando. Si se usan dos en una fila, se interpretan como uno; doblar parece dar un comportamiento consistente. – jtpereyda

1

This answer es el más cercano que he visto a la explicación de la locura de los argumentos de línea de comandos de Windows. No es tan simple como parece inicialmente.

No debería tener que escapar de U + FF02 en general. El problema es que si terminas pasando ese personaje a una línea de comando que no admite Unicode, se reducirá a su equivalente no compatible, la cita ASCII, en cuyo punto se vuelve peligroso. Si su comando va a una herramienta que no admite Unicode, debe doblarlo a ASCII antes de aplicar el argumento de escape, en lugar de dejar que la herramienta en el otro extremo lo haga.

(Por lo general, el problema será cuando esa herramienta use C stdlib para leer sus argumentos. Esto se define en términos de 8-bit char; la implementación de Windows stdlib usa la página de códigos del sistema predeterminada ("ANSI") para codificar la cadena a 8 bits, y esa página de códigos nunca es un formato de transformación Unicode por lo que siempre perderá caracteres.)

0

Mi intento de escapar:

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

Este es un ejemplo de cómo una cotización puede estar presente en una cadena de búsqueda Google:

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

La primera línea de la pregunta especifica que el OP desea "escapar de una cadena ** desconocida". El método proporcionado no se puede utilizar para dicha cadena. – Spooky