Pergunta

Eu estou tentando passar argumentos de linha de comando para um aplicativo C #, mas tenho problema em passar algo assim

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

mesmo se eu adicionar " " ao argumento.

Aqui está o meu 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)
            {
            }
        }
        }

E aqui está o que eu estou passando:

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

O problema é que posso obter o primeiro eo segundo args corretamente, mas o último fica como C:\Documents.

Qualquer ajuda?

Foi útil?

Solução

Eu corri um cheque e verificou o problema. Surpreendeu-me, mas é a última \ no primeiro argumento.

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

Esta precisa de mais explicação, alguém tem uma idéia? Estou inclinado a chamá-lo de um bug.


Parte 2, eu corri alguns testes mais e

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

se torna

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

action Um pouco Google dá algumas dicas de um blog de Jon Galloway , as regras básicas são:

  • a barra invertida é o caractere de escape
  • sempre escapar citações
  • única escapar barras invertidas quando eles precedem uma citação.

Outras dicas

Para adicionar de Ian Kemp resposta

Se você conjunto é chamado de "myprog.exe" e você passa na seqüência de "C: \ Documents and Settings \ All Users \ Start Menu \ Programs \ App nome" link para que

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

a string "C: \ Documents and Settings \ All Users \ Start Menu \ Programs nome \ App"

estará em args [0].

Para adicionar o que todo mundo já disse, pode ser um problema de escapar. Você deve escapar de seus barras invertidas por outra barra invertida.

Deve ser algo como:

C: \> myprog.exe "C: \\ Documents and Settings \\ Todos os usuários \\ Start Menu \\ nome Programas \\ App"

Eu observei o mesmo problema irritante recentemente, e decidiu escrever um analisador para analisar a matriz de argumentos de linha de comando para fora eu mesmo.

Nota: o problema é que os argumentos .NET linha de comando passados ??ao static void Main (string [] args) escapes de função \" e \\ Isso ocorre por design, pois você pode realmente quer passar um argumento que tem. uma citação ou barra invertida nela um exemplo:.

dizer que você queria passar o seguinte como um único argumento:

-msg: Ei, "Onde você em"

por exemplo.

SampleApp -msg: "Ei, \" Onde você a? \ ""

Seria como enviá-lo com o comportamento padrão.

Se você não vê uma razão para alguém tem que escapar aspas ou barras invertidas para o seu programa, você pode utilizar seu próprio analisador para analisar a linha de comando, como a seguir.

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

teria um args [0] = c: \ test" arg1 arg2

O que você esperaria é args [0] = c:. \ Test \ e, em seguida, args [1] = arg1 e args [2] = arg2

A seguir função analisa os argumentos em uma lista com esse comportamento simplificado.

Note, arg [0] é o nome do programa usando o código abaixo. (Você chama List.ToArray () para converter a lista resultante de uma matriz de cadeia.)

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;
}

Em resposta a resposta de WWC, Jamezor comentou que seu código irá falhar se o primeiro caractere é uma citação.

Para corrigir esse problema, você pode substituir o caso StartToken com este:

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

O que é exatamente o problema? De qualquer forma aqui vai um conselho geral:

Verifique se o seu método principal (em Program.cs) é definido como:

void Main(string[] args)

Então args é uma matriz que contém os argumentos de linha de comando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top