Analyse en ligne de commande C # des chemins cités et évitant les caractères d’échappement

Comment est-il possible d’parsingr des 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 citées, par exemple:

example.exe un deux “trois quatre”

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

Cependant, args [] ne parsingra pas la propriété “C: \ Example \” en tant qu’argument. Au lieu de cela, il fournira l’argument sous la forme “C: \ Exemple” “(avec la citation supplémentaire incluse.) Cela est dû au fait que la barre oblique inverse dans le chemin est traitée comme un caractère d’échappement et donc à la citation de fin que l’utilisateur a fournie dans la commande -line devient une partie de l’argument.

.par exemple:

example.exe un “C: \ InputFolder” “C: \ OutuptFolder \”

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

Un kludge facile pourrait être:

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

Cependant, je suis sûr qu’il existe une meilleure pratique pour cela. Comment peut-on parsingr correctement une ligne de commande qui inclut des chemins, empêchant le tableau args [] de se remplir de manière incorrecte avec des piqûres analysées pour les caractères d’échappement?

REMARQUE: je ne voudrais pas inclure une bibliothèque complète d’parsing en ligne de commande dans mon projet! Je n’ai besoin que de gérer les 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’parsings en ligne de commande «évier de cuisine».

NOTE AUSSI: Pour autant que je sache, cette question ne fait pas double emploi. Tandis que d’autres questions portent sur l’parsing générique en ligne de commande, cette question est spécifique au problème introduit par les chemins d’access lorsque certaines de leurs parties sont interprétées comme des séquences d’échappement.

Pas une réponse, mais voici quelques informations et explications de Jeffrey Tan, Support technique de la communauté en ligne de Microsoft (12/7/2006):

Remarque: il ne s’agit pas d’une défaite de code, mais bien de la conception, car les backslashe sont normalement utilisés pour échapper à certains caractères spéciaux. En outre, cet algorithme est identique à celui des arguments de la ligne de commande Win32 qui parsingnt la fonction CommandLineToArgvW. Voir la section Remarques ci-dessous: http://msdn2.microsoft.com/en-us/library/bb776391.aspx

Fait également référence à la méthode FX Environment.GetCommandLineArgs pour une explication plus détaillée du comportement de la gestion des barres obliques.

Personnellement, je pense que c’est un problème, et je suis surpris de ne pas l’avoir été auparavant. Ou peut-être que je ne le sais pas? Le remplacement aveugle des guillemets par des barres obliques ne me semble toutefois pas une solution. Je vote la question, parce que c’était une révélation.

J’aime votre idée:

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

Il est propre et n’aura d’effet que si le problème existe.

J’ai eu la même frustration. Ma solution consistait à 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 ssortingng or non-quoted ssortingngs followed by whitespace ssortingng 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().Concat( m.Groups[2].Captures.Cast()). 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?