Passando argumentos de linha de comando em C #
-
19-08-2019 - |
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?
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 ??p>
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.