parameter - Pasando argumentos de línea de comando en C#
ejecutar varios comandos cmd desde c# (6)
¿Cuál es el problema exactamente? De todos modos aquí hay algunos consejos generales:
Asegúrese de que su método principal (en Program.cs) se define como:
void Main(string[] args)
Entonces args es una matriz que contiene los argumentos de la línea de comandos.
Estoy tratando de pasar argumentos de línea de comandos a una aplicación de 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 aquí está 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 primero y el segundo argumento correctamente, pero el último se obtiene como C:/Documents
.
¿Alguna ayuda?
Acabo de hacer un cheque 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, me hice algunas pruebas más y
"X://aa aa//" "X://aa aa/" next
se convierte en
X://aa aa/
X://aa aa" next
Una pequeña acción de Google da una idea de un blog de Jon Galloway , las reglas básicas son:
- la barra invertida es el personaje de escape
- siempre escapa de las citas
- Sólo escape barras invertidas cuando preceden a una cita.
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 de 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;
}
}
Noté el mismo problema molesto recientemente, y decidí escribir un analizador para analizar el conjunto de argumentos de la línea de comandos.
Nota: el problema es que los Argumentos de la Línea de Comando .NET pasados a la función Main estática vacía (string [] args) se escapa / "y //. Esto es por diseño, ya que es posible que desee pasar un argumento que tenga una cita o barra invertida en él. Un ejemplo:
Digamos que querías pasar lo siguiente como un solo argumento:
-msg: Oye, "¿Dónde estás?"
p.ej.
sampleapp -msg: "Hey, /" ¿Dónde estás? / ""
Sería cómo enviarlo con el comportamiento por defecto.
Si no ve una razón para que alguien tenga que escapar de comillas o barras invertidas para su programa, puede utilizar su propio analizador para analizar la línea de comandos, como se muestra a continuación.
ES DECIR. [program] .exe "C: / test /" arg1 arg2
tendría un args [0] = c: / prueba "arg1 arg2
Lo que cabría esperar 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.
Tenga en cuenta que arg [0] es el nombre del programa que utiliza el siguiente código. (Llamas 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;
}
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 invertidas por otra barra invertida.
Debería ser algo como:
C: /> myprog.exe "C: // Documents and Settings // Todos los usuarios // Menú de inicio // Programas // Nombre de la aplicación"
Para agregar la respuesta de Ian Kemp
Si su ensamblaje se llama "myProg.exe" y pasa la cadena "C: / Documents and Settings / Todos los usuarios / Menú de inicio / Programas / Nombre de la aplicación" para
C:/>myprog.exe "C:/Documents and Settings/All Users/Start Menu/Programs/App name"
la cadena "C: / Documents and Settings / Todos los usuarios / Menú de inicio / Programas / Nombre de la aplicación"
estará en args [0].