J'essaye de passer des arguments de ligne de commande à une application C #, mais j'ai du mal à passer quelque chose comme ça
"C:\Documents and Settings\All Users\Start Menu\Programs\App name"
même si j'ajoute " "
à l'argument.
Voici mon code:
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)
{
}
}
}
Et voici ce que je passe:
C:\WINDOWS\Uninstaller.exe "C:\Program Files\Application name\" "username" "C:\Documents and Settings\All Users\Start Menu\Programs\application name"
Le problème est que je peux obtenir le premier et le second argument correctement, mais le dernier qu'il obtient comme C:\Documents
.
De l'aide?
J'ai juste fait une vérification et vérifié le problème. Cela m'a surpris, mais c'est le dernier\du premier argument.
"C:\Program Files\Application name\" <== remove the last '\'
Cela nécessite plus d'explications, est-ce que quelqu'un a une idée? J'ai tendance à appeler cela un bug.
Partie 2, j'ai effectué quelques tests supplémentaires et
"X:\\aa aa\\" "X:\\aa aa\" next
devient
X:\\aa aa\
X:\\aa aa" next
Une petite action de Google donne un aperçu d'un blog de Jon Galloway , les règles de base sont:
Pour ajouter la réponse de Ian Kemp
Si votre Assembly s'appelle "myProg.exe" et que vous passez la chaîne "C:\Documents and Settings\All Users\Start Menu\Programs\App name", alors
C:\>myprog.exe "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
la chaîne "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
sera à args [0].
J'ai remarqué le même problème ennuyeux récemment et j'ai décidé d'écrire un analyseur pour analyser moi-même le tableau d'arguments de ligne de commande.
Remarque: le problème est que les arguments .NET CommandLine passés à la fonction static void Main (string [] args) échappent à\"et \\. C'est par conception, car vous pouvez en fait passer un argument avec barre oblique inverse. Un exemple:
disons que vous vouliez passer ce qui suit comme argument unique:
-msg: Hé, "Où es-tu?"
par exemple.
sampleapp -msg: "Hé, \" Où es-tu?\""
Serait comment l'envoyer avec le comportement par défaut.
Si vous ne voyez aucune raison pour que quiconque doive échapper des guillemets ou des barres obliques inverses pour votre programme, vous pouvez utiliser votre propre analyseur pour analyser la ligne de commande, comme ci-dessous.
C'EST À DIRE. [programme] .exe "C:\test \" arg1 arg2
aurait un args [0] = c:\test "arg1 arg2
Ce que vous attendez, c'est args [0] = c:\test\puis args [1] = arg1 et args [2] = arg2.
La fonction ci-dessous analyse les arguments dans une liste avec ce comportement simplifié.
Notez que arg [0] est le nom du programme utilisant le code ci-dessous. (Vous appelez List.ToArray () pour convertir la liste résultante en un tableau de chaînes.)
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;
}
Pour ajouter à ce que tout le monde a déjà dit, cela pourrait être un problème échappant. Vous devez échapper vos contre-obliques par une autre contre-oblique.
Devrait être quelque chose comme:
C: \> myprog.exe "C: \\ Documents and Settings \\ All Users \\ Start Menu \\ Programs \\ App name"
En réponse à la réponse de WWC, Jamezor a fait remarquer que son code échouera si le premier caractère est une citation.
Pour résoudre ce problème, vous pouvez remplacer le cas StartToken par ceci:
if (eps == enumParseState.StartToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
//Skip whitespace
}
else if (c == '"')
{
eps = enumParseState.InQuote;
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}
Quel est le problème exactement? Quoi qu'il en soit, voici quelques conseils généraux:
Assurez-vous que votre méthode Main (dans Program.cs) est définie comme:
void Main(string[] args)
Alors args est un tableau contenant les arguments de ligne de commande.