Pregunta

Estoy tratando de pasar argumentos de línea de comandos a una aplicación C #, pero tengo problemas para pasar algo como esto

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

incluso si agrego " " 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 esto 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 obtener el primer y el segundo argumento correctamente, pero el último se obtiene como C: \ Documents .

¿Alguna ayuda?

¿Fue útil?

Solución

Acabo de hacer una verificación y verifiqué 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, realicé algunas pruebas más y

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

se convierte

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

Una pequeña acción de Google da una idea de blog de Jon Galloway , las reglas básicas son:

  • la barra diagonal inversa es el carácter de escape
  • siempre escapa de comillas
  • solo escapan barras diagonales cuando preceden una cita.

Otros consejos

Para agregar la respuesta de Ian Kemp

Si su ensamblaje se llama " myProg.exe " y pasa la cadena "C: \ Documentos y configuraciones \ Todos los usuarios \ Menú Inicio \ Programas \ Nombre de la aplicación" enlace así

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

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

estará en args [0].

Para agregar a lo que todos los demás ya han dicho, podría ser un problema que se escapa. Deberías escapar de tus barras invertidas por otra barra invertida.

Debería ser algo como:

C: \ > myprog.exe " C: \\ Documentos y configuraciones \\ Todos los usuarios \\ Menú de inicio \\ Programas \\ Nombre de la aplicación "

Recientemente noté el mismo problema molesto, 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 la línea de comandos de .NET pasados ??a la función Main (string [] args) vacía estática escapa \ " y \\. Esto es por diseño, ya que es posible que desee pasar un argumento que tenga una cita o una barra invertida. Un ejemplo:

digamos que desea pasar lo siguiente como un argumento único:

  

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

ej.

  

sampleapp -msg: " Hola, \ " Donde   en? \ " "

Sería cómo enviarlo con el comportamiento predeterminado.

Si no ve una razón para que alguien tenga que escapar de las comillas o las barras diagonales inversas 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 \ " arg1 arg2

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

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

La siguiente función analiza los argumentos en una lista con este comportamiento simplificado.

Nota, arg [0] es el nombre del programa usando el siguiente código. (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;
}

En respuesta a la respuesta de WWC, Jamezor comentó que su código fallará si el primer personaje 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;
                }
            }

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

Asegúrese de que su método Main (en Program.cs) esté definido como:

void Main(string[] args)

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top