2009-03-17 21 views
16

estoy tratando de pasar argumentos de línea de comandos para una aplicación C#, pero tengo un problema que pasa algo como estopasar argumentos de línea de comandos en C#

"C:\Documents and Settings\All Users\Start Menu\Programs\App name" 

incluso si añado " " al argumento.

Aquí está mi código:

public ObjectModel(String[] args) 
    { 
     if (args.Length == 0) return; //no command line arg. 
     //System.Windows.Forms.MessageBox.Show(args.Length.ToString()); 
     //System.Windows.Forms.MessageBox.Show(args[0]); 
     //System.Windows.Forms.MessageBox.Show(args[1]); 
     //System.Windows.Forms.MessageBox.Show(args[2]); 
     //System.Windows.Forms.MessageBox.Show(args[3]); 
     if (args.Length == 3) 
     { 
      try 
      { 
       RemoveInstalledFolder(args[0]); 
       RemoveUserAccount(args[1]); 
       RemoveShortCutFolder(args[2]); 
       RemoveRegistryEntry(); 
      } 
      catch (Exception e) 
      { 
      } 
     } 
     } 

Y aquí es lo que estoy pasando:

C:\WINDOWS\Uninstaller.exe "C:\Program Files\Application name\" "username" "C:\Documents and Settings\All Users\Start Menu\Programs\application name" 

El problema es que puedo conseguir el primero y el segundo args correctamente, pero el último se pone como C:\Documents.

¿Algún ayuda?

+1

¿Qué está tratando de empezar esto desde?Línea de comando u otro programa? Si este último, ¿cuál es el idioma? – sharptooth

+0

¿Qué sucede cuando pasa un argumento como este a su aplicación? – Draco

+0

¿Puede pasar el código que intenta acceder al argumento y también la línea de comando completa que está escribiendo, como c: \ myapp.exe "c: \ documents \ appname" –

Respuesta

25

acabo ejecutó un cheque y verificó el problema. Me sorprendió, pero es el último \ en el primer argumento.

"C:\Program Files\Application name\" <== remove the last '\' 

Esto necesita más explicación, ¿alguien tiene una idea? Me inclino a llamarlo un error.


Parte 2, me encontré con un par de pruebas más y

"X:\\aa aa\\" "X:\\aa aa\" next 

convierte

X:\\aa aa\ 
X:\\aa aa" next 

un poco de acción Google da una idea de un blog by Jon Galloway, las reglas básicas son:

  • la barra diagonal inversa es la es cabo carácter
  • siempre escapadas comillas
  • solo escapan hacia atrás cuando preceden a una comilla.
+0

Se soluciona eliminando \ desde el primer argumento. Muchas gracias –

+0

Si quiere esa barra invertida trasera, puede agregar otra. Es decir, "abd \ \ "en la línea de comandos da como resultado un argumento de" abd \ ". –

+0

@Jim: Sí, la primera parte del ejemplo demuestra que. –

0

¿Cuál es exactamente el problema? De todos modos aquí está algunos consejos generales:

Asegúrese de que el método principal (en Program.cs) se define como:

void Main(string[] args) 

Entonces args es una matriz que contiene los argumentos de línea de comandos.

5

Para añadir la respuesta de Ian Kemp

Si el montaje se llama "myprog.exe" y se pasa en la cadena "C: \ Documents and Settings \ All Users \ Menú Inicio \ Programas \ App nombre de" enlace para

C:\>myprog.exe "C:\Documents and Settings\All Users\Start Menu\Programs\App name" 

la cadena "C: \ Documents and Settings \ All Users \ Menú inicio \ nombre de Programas \ App"

estará en args [0].

+3

Sin embargo, el caso que nos ocupa es que si llama a 'myprog.exe" c: \ one \ "" two "" three "', entonces args [0] será 'c: \ one" two three'. Pruébelo –

1

Para agregar a lo que todos los demás ya han dicho, podría ser un problema de escape. Debería escapar de sus barras diagonales por otra barra invertida.

debe ser algo como:

C: \> myprog.exe "C: \\ Documents and Settings \\ \\ Todos los usuarios Menú Inicio Programas \\ \\ Nombre de la aplicación"

+0

Bastante bastante, es la última barra invertida en el primer argumento. Lo comprobé. –

+1

Pero los dobles \\ son una tontería en la entrada, solo son útiles en la fuente de C# –

+0

pero funcionan :) pruébalo – Aamir

1

Noté el mismo problema molesto recientemente, y decidí escribir un analizador para analizar la matriz de argumentos de la línea de comandos.

Nota: el problema es que los argumentos de .NET CommandLine pasados ​​a la función void estática principal (string [] args) escapa \ "y \\. Esto es por diseño, ya que es posible que desee pasar un argumento que tiene un presupuesto o barra invertida en ella un ejemplo:.

dicen que quería pasar a la siguiente como un solo argumento:

-msg: "¿Dónde estás" Hey,

por ejemplo,

SampleApp -msg: "Hey, \" Donde en \ ""

Sería la forma de enviar con el comportamiento por defecto?.

Si no ve un motivo para que alguien tenga que escapar de las comillas o barras diagonales para su programa, puede utilizar su propio analizador para analizar la línea de comandos, como se muestra a continuación.

IE. [programa] .exe "C: \ test \" arg2 arg1

tendría un args [0] = c: \ test" arg2 arg1

Lo que cabe esperar es args [0] = c: \ test \ y luego args [1] = arg1 y args [2] = arg2.

la función debajo analiza los argumentos en una lista con este comportamiento simplificado.

Nota, arg [0] es el programa nombre usando el código siguiente. (Usted llama a List.ToArray() para convertir la lista resultante en una matriz de cadenas.)

protected enum enumParseState : int { StartToken, InQuote, InToken }; 
public static List<String> ManuallyParseCommandLine() 
{ 
    String CommandLineArgs = Environment.CommandLine.ToString(); 

    Console.WriteLine("Command entered: " + CommandLineArgs); 

    List<String> listArgs = new List<String>(); 

    Regex rWhiteSpace = new Regex("[\\s]"); 
    StringBuilder token = new StringBuilder(); 
    enumParseState eps = enumParseState.StartToken; 

    for (int i = 0; i < CommandLineArgs.Length; i++) 
    { 
     char c = CommandLineArgs[i]; 
    // Console.WriteLine(c.ToString() + ", " + eps); 
     //Looking for beginning of next token 
     if (eps == enumParseState.StartToken) 
     { 
      if (rWhiteSpace.IsMatch(c.ToString())) 
      { 
       //Skip whitespace 
      } 
      else 
      { 
       token.Append(c); 
       eps = enumParseState.InToken; 
      } 


     } 
     else if (eps == enumParseState.InToken) 
     { 
      if (rWhiteSpace.IsMatch(c.ToString())) 
      { 
       Console.WriteLine("Token: [" + token.ToString() + "]"); 
       listArgs.Add(token.ToString().Trim()); 
       eps = enumParseState.StartToken; 

       //Start new token. 
       token.Remove(0, token.Length); 
      } 
      else if (c == '"') 
      { 
       // token.Append(c); 
       eps = enumParseState.InQuote; 
      } 
      else 
      { 
       token.Append(c); 
       eps = enumParseState.InToken; 
      } 

     } 
      //When in a quote, white space is included in the token 
     else if (eps == enumParseState.InQuote) 
     { 
      if (c == '"') 
      { 
       // token.Append(c); 
       eps = enumParseState.InToken; 
      } 
      else 
      { 
       token.Append(c); 
       eps = enumParseState.InQuote; 
      } 

     } 


    } 
    if (token.ToString() != "") 
    { 
     listArgs.Add(token.ToString()); 
     Console.WriteLine("Final Token: " + token.ToString()); 
    } 
    return listArgs; 
} 
+1

Esto parece quebrarse si el primer caracter es una cita – Jamezor

+0

@Jamezor - Usted 'estas en lo correcto. Ver mi respuesta para una corrección. – guesser

1

En respuesta a la respuesta de WWC, Jamezor comentó que su código fallará si el primer carácter es una cita.

Para solucionar ese problema, puede reemplazar el caso StartToken con esto:

  if (eps == enumParseState.StartToken) 
      { 
       if (rWhiteSpace.IsMatch(c.ToString())) 
       { 
        //Skip whitespace 
       } 
       else if (c == '"') 
       { 
        eps = enumParseState.InQuote; 
       } 
       else 
       { 
        token.Append(c); 
        eps = enumParseState.InToken; 
       } 
      } 
Cuestiones relacionadas