2009-05-22 11 views
21

Comment est-il possible d'analyser les arguments de ligne de commande devant être interprétés comme des chemins? args [] contient des chaînes qui sont automatiquement jointes si elles sont cotées, par exemple:C# Analyse en ligne de commande des chemins cités et évitement des caractères d'échappement

exemple.exe un deux "trois quatre"

args[0] = one 
args[1] = two 
args[2] = three four 

Cependant, args [] ne parse propriété « C: \ Exemple \ "comme argument. Plutôt, il fournira l'argument comme "C: \ Example" "(avec la citation supplémentaire incluse.) Cela est dû à la barre oblique inverse dans le chemin étant traitée comme un caractère d'échappement et donc la citation de fin que l'utilisateur a fourni sur la commande -ligne devient une partie de l'argument

.eg.

un exemple.exe "C: \ InputFolder" "C: \ OutuptFolder \"

args[0] = one 
args[1] = C:\InputFolder" 
args[2] = C:\OutputFolder" 

une bidouille facile pourrait être:

_path = args[i].Replace("\"", @"\"); 

Cependant, je suis sûr qu'il existe une meilleure pratique pour cela. Comment peut-on correctement analyser une ligne de commande qui inclut des chemins, empêchant le tableau args [] d'être incorrectement peuplé avec des piqûres qui ont été analysées pour les caractères d'échappement?

REMARQUE: Je ne souhaite pas inclure une bibliothèque complète d'analyse en ligne de commande dans mon projet! Je n'ai besoin que de gérer des chemins cités et je souhaite le faire de manière "manuelle". Veuillez ne pas recommander NConsoler, Mono ou toute autre grande bibliothèque d'analyse de ligne de commande "sink".

AUSSI NOTE: Pour autant que je peux dire, ce n'est pas une question en double. Alors que d'autres questions se concentrent sur l'analyse syntaxique en ligne de commande générique, cette question est spécifique au problème que les chemins introduisent lorsque des parties de ceux-ci sont interprétées comme des séquences d'échappement.

+0

Où exactement voyez-vous ce caractère supplémentaire? J'utilise un compilateur d'extraits. Voici la principale .. chaîne s = args [0]; \t \t Console.WriteLine (s); Et cela fonctionne comme il se doit. – shahkalpesh

+0

@shahkalpesh: Ne parlez pas de votre compilateur de snippets, mais essayez de l'exécuter depuis la ligne de commande, et fournissez votre programme avec un argument se terminant par \ "(backslash-doublequote) Comme l'a dit ebwi, j'ai ouvert les yeux –

+0

Désolé, je n'ai pas bien compris l'argument d'entrée – shahkalpesh

Répondre

8

Pas une réponse, mais voici quelques background and explanation de Jeffrey Tan, le soutien communautaire en ligne Microsoft (12/7/2006):

Note: ce n'est pas pas une défaite de code mais par la conception, depuis backslashe est normalement utilisé pour échapper à certains caractères spéciaux . En outre, cet algorithme est le même que la commande Win32 arguments d'analyse syntaxique CommandLineToArgvW. Voir les Remarques section ci-dessous: http://msdn2.microsoft.com/en-us/library/bb776391.aspx

fait également référence à la méthode FX Environment.GetCommandLineArgs pour plus d'explications du comportement de manipulation de barre oblique.

Personnellement, je pense que c'est un frein, et je suis surpris que je n'ai pas été un peu avant. Ou peut-être que je l'ai et je ne le sais pas? Cependant, le remplacement à l'aveugle de guillemets par des barres obliques ne me semble pas être une solution. Je vote la question, parce que c'était une révélation.

1

J'aime votre idée:

_path = args[i].Replace("\"", @"\"); 

Il est propre et n'a aucun effet à moins que le problème existe.

+0

Mais cela ne fonctionnera pas si vous avez: example.exe un "C: \ InputFolder \" "C: \ OutuptFolder \" car les deux chemins seront concaténés comme arg [1] = C: \ InputFolder "C: \ Outpurfolder" –

1

J'ai eu la même frustration.Ma solution était d'utiliser des expressions régulières. Mon entrée attendue est une liste de chemins, dont certains peuvent être cités. Le kludge ci-dessus ne fonctionne que si tous les derniers arguments sont cités.

// Capture quoted string or non-quoted strings followed by whitespace 
string exp = @"^(?:""([^""]*)""\s*|([^""\s]+)\s*)+"; 
Match m = Regex.Match(Environment.CommandLine, exp); 

// Expect three Groups 
// group[0] = entire match 
// group[1] = matches from left capturing group 
// group[2] = matches from right capturing group 
if (m.Groups.Count < 3) 
    throw new ArgumentException("A minimum of 2 arguments are required for this program"); 

// Sort the captures by their original postion 
var captures = m.Groups[1].Captures.Cast<Capture>().Concat(
       m.Groups[2].Captures.Cast<Capture>()). 
       OrderBy(x => x.Index). 
       ToArray(); 

// captures[0] is the executable file 
if (captures.Length < 3) 
    throw new ArgumentException("A minimum of 2 arguments are required for this program"); 

Quelqu'un peut-il voir une regex plus efficace?

Questions connexes