Meilleur moyen d’parsingr les arguments de ligne de commande en C #?

Lorsque vous créez des applications de console qui prennent des parameters, vous pouvez utiliser les arguments transmis à Main(ssortingng[] args) .

Dans le passé, j’ai simplement indexé / bouclé ce tableau et fait quelques expressions régulières pour en extraire les valeurs. Cependant, lorsque les commandes deviennent plus compliquées, l’parsing peut devenir assez moche.

Donc je suis intéressé par:

  • Bibliothèques que vous utilisez
  • Motifs que vous utilisez

Supposez que les commandes respectent toujours les normes communes telles que les réponses ici .

Je suggère fortement d’utiliser NDesk.Options ( Documentation ) et / ou Mono.Options (même API, différents espaces de noms). Un exemple de la documentation :

 bool show_help = false; List names = new List (); int repeat = 1; var p = new OptionSet () { { "n|name=", "the {NAME} of someone to greet.", v => names.Add (v) }, { "r|repeat=", "the number of {TIMES} to repeat the greeting.\n" + "this must be an integer.", (int v) => repeat = v }, { "v", "increase debug message verbosity", v => { if (v != null) ++verbosity; } }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List extra; try { extra = p.Parse (args); } catch (OptionException e) { Console.Write ("greet: "); Console.WriteLine (e.Message); Console.WriteLine ("Try `greet --help' for more information."); return; } 

J’aime beaucoup la bibliothèque d’interface de ligne de commande ( http://commandline.codeplex.com/ ). Il a une manière très simple et élégante de configurer les parameters via les atsortingbuts:

 class Options { [Option("i", "input", Required = true, HelpText = "Input file to read.")] public ssortingng InputFile { get; set; } [Option(null, "length", HelpText = "The maximum number of bytes to process.")] public int MaximumLenght { get; set; } [Option("v", null, HelpText = "Print details during execution.")] public bool Verbose { get; set; } [HelpOption(HelpText = "Display this help screen.")] public ssortingng GetUsage() { var usage = new SsortingngBuilder(); usage.AppendLine("Quickstart Application 1.0"); usage.AppendLine("Read user manual for usage instructions..."); return usage.ToSsortingng(); } } 

La bibliothèque WPF TestApi est fournie avec l’un des parsingurs de ligne de commande les plus performants pour le développement C #. Je recommande fortement de l’examiner, à partir du blog d’ Ivo Manolov sur l’API :

 // EXAMPLE #2: // Sample for parsing the following command-line: // Test.exe /verbose /runId=10 // This sample declares a class in which the strongly- // typed arguments are populated public class CommandLineArguments { bool? Verbose { get; set; } int? RunId { get; set; } } CommandLineArguments a = new CommandLineArguments(); CommandLineParser.ParseArguments(args, a); 

On dirait que tout le monde a ses propres parsingurs de ligne de commande pour animaux de compagnie, je pense que je ferais mieux d’append le mien aussi :).

http://bizark.codeplex.com/

Cette bibliothèque contient un parsingur de ligne de commande qui initialisera une classe avec les valeurs de la ligne de commande. Il a une tonne de fonctionnalités (je le construis depuis de nombreuses années).

De la documentation …

L’parsing de ligne de commande dans le framework BizArk présente les fonctionnalités suivantes:

  • Initialisation automatique: les propriétés de la classe sont automatiquement définies en fonction des arguments de la ligne de commande.
  • Propriétés par défaut: Envoyer une valeur sans spécifier le nom de la propriété.
  • Conversion de valeur: Utilise la puissante classe ConvertEx incluse dans BizArk pour convertir les valeurs au type approprié.
  • Indicateurs booléens: Les indicateurs peuvent être spécifiés en utilisant simplement l’argument (ex, / b pour true et / b- pour false) ou en ajoutant la valeur true / false, yes / no, etc.
  • Tableaux d’arguments: ajoutez simplement plusieurs valeurs après le nom de la ligne de commande pour définir une propriété définie en tant que tableau. Ex, / x 1 2 3 remplira x avec le tableau {1, 2, 3} (en supposant que x est défini comme un tableau d’entiers).
  • Alias ​​de ligne de commande: une propriété peut prendre en charge plusieurs alias de ligne de commande. Par exemple, l’aide utilise l’alias?.
  • Reconnaissance partielle des noms: vous n’avez pas besoin d’épeler le nom complet ou l’alias, il vous suffit d’épeler suffisamment pour que l’parsingur puisse désambiguïser la propriété / l’alias des autres.
  • Prend en charge ClickOnce: peut initialiser les propriétés même si elles sont spécifiées comme chaîne de requête dans une URL pour les applications déployées ClickOnce. La méthode d’initialisation de la ligne de commande détecte si elle s’exécute en tant que ClickOnce ou non, de sorte que votre code n’a pas besoin de changer lors de son utilisation.
  • Crée automatiquement /? help: Cela inclut un formatage agréable qui prend en compte la largeur de la console.
  • Charger / enregistrer des arguments de ligne de commande dans un fichier: Cela est particulièrement utile si vous souhaitez exécuter plusieurs fois de grands ensembles complexes d’arguments de ligne de commande.

J’ai écrit un parsingur de ligne de commande C # depuis un certain temps. C’est à: http://www.codeplex.com/CommandLineArguments

CLAP (parsingur d’argument de ligne de commande) possède une API utilisable et est merveilleusement documentée. Vous créez une méthode en annotant les parameters. https://github.com/adrianaisemberg/CLAP

Il existe de nombreuses solutions à ce problème. Pour être complet et pour proposer une alternative si quelqu’un désire, j’ajoute cette réponse pour deux classes utiles dans ma bibliothèque de codes Google .

Le premier est ArgumentList, qui est uniquement responsable de l’parsing des parameters de ligne de commande. Il collecte des paires nom-valeur définies par les commutateurs ‘/ x: y’ ou ‘-x = y’ et collecte également une liste d’entrées «non nommées». Son utilisation de base est discutée ici , regardez la classe ici .

La seconde partie est le CommandInterpreter qui crée une application de ligne de commande entièrement fonctionnelle à partir de votre classe .Net. Par exemple:

 using CSharpTest.Net.Commands; static class Program { static void Main(ssortingng[] args) { new CommandInterpreter(new Commands()).Run(args); } //example 'Commands' class: class Commands { public int SomeValue { get; set; } public void DoSomething(ssortingng svalue, int ivalue) { ... } 

Avec l’exemple de code ci-dessus, vous pouvez exécuter les opérations suivantes:

Program.exe DoSomething “valeur de chaîne” 5

— ou —

Program.exe thingomething / ivalue = 5 -svalue: “valeur de chaîne”

C’est aussi simple que cela ou aussi complexe que vous en avez besoin. Vous pouvez consulter le code source , afficher l’aide ou télécharger le binary .

J’aime celle-là , car vous pouvez “définir des règles” pour les arguments, nécessaires ou non, …

ou si vous êtes un gars Unix, vous pourriez aimer le port GNU Getopt .NET .

Vous pouvez aimer mon seul Rug.Cmd

Analyseur d’argument de ligne de commande facile à utiliser et extensible. Poignées: Bool, Plus / Minus, Chaîne, Liste de chaînes, CSV, Enumeration.

Construit en ‘/?’ mode d’aide.

Construit en ‘/ ??’ et modes de générateur de document ‘/? D’.

 static void Main(ssortingng[] args) { // create the argument parser ArgumentParser parser = new ArgumentParser("ArgumentExample", "Example of argument parsing"); // create the argument for a ssortingng SsortingngArgument SsortingngArg = new SsortingngArgument("Ssortingng", "Example ssortingng argument", "This argument demonstrates ssortingng arguments"); // add the argument to the parser parser.Add("/", "Ssortingng", SsortingngArg); // parse arguemnts parser.Parse(args); // did the parser detect a /? argument if (parser.HelpMode == false) { // was the ssortingng argument defined if (SsortingngArg.Defined == true) { // write its value RC.WriteLine("Ssortingng argument was defined"); RC.WriteLine(SsortingngArg.Value); } } } 

Edit: Ceci est mon projet et en tant que tel, cette réponse ne doit pas être considérée comme une approbation d’un tiers. Cela dit, je l’utilise pour tous les programmes basés sur la ligne de commande que j’écris, c’est open source et j’espère que d’autres pourront en bénéficier.

Il y a un parsingur d’argument de ligne de commande sur http://www.codeplex.com/commonlibrarynet

Il peut parsingr les arguments en utilisant
1. atsortingbuts
2. appels explicites
3. ligne unique de plusieurs arguments OU tableau de chaînes

Il peut gérer des choses comme les suivantes:

config : Qa – date de début : $ { today } – région : ‘New York’ Settings01

C’est très facile à utiliser.

C’est un gestionnaire que j’ai écrit en fonction de la classe d’ Options Novell.

Celui-ci est destiné aux applications de console qui exécutent une boucle de style while while (input !="exit") , une console interactive telle qu’une console FTP par exemple.

Exemple d’utilisation:

 static void Main(ssortingng[] args) { // Setup CommandHandler handler = new CommandHandler(); CommandOptions options = new CommandOptions(); // Add some commands. Use the v syntax for passing arguments options.Add("show", handler.Show) .Add("connect", v => handler.Connect(v)) .Add("dir", handler.Dir); // Read lines System.Console.Write(">"); ssortingng input = System.Console.ReadLine(); while (input != "quit" && input != "exit") { if (input == "cls" || input == "clear") { System.Console.Clear(); } else { if (!ssortingng.IsNullOrEmpty(input)) { if (options.Parse(input)) { System.Console.WriteLine(handler.OutputMessage); } else { System.Console.WriteLine("I didn't understand that command"); } } } System.Console.Write(">"); input = System.Console.ReadLine(); } } 

Et la source:

 ///  /// A class for parsing commands inside a tool. Based on Novell Options class (http://www.ndesk.org/Options). ///  public class CommandOptions { private Dictionary> _actions; private Dictionary _actionsNoParams; ///  /// Initializes a new instance of the  class. ///  public CommandOptions() { _actions = new Dictionary>(); _actionsNoParams = new Dictionary(); } ///  /// Adds a command option and an action to perform when the command is found. ///  /// The name of the command. /// An action delegate /// The current CommandOptions instance. public CommandOptions Add(ssortingng name, Action action) { _actionsNoParams.Add(name, action); return this; } ///  /// Adds a command option and an action (with parameter) to perform when the command is found. ///  /// The name of the command. /// An action delegate that has one parameter - ssortingng[] args. /// The current CommandOptions instance. public CommandOptions Add(ssortingng name, Action action) { _actions.Add(name, action); return this; } ///  /// Parses the text command and calls any actions associated with the command. ///  /// The text command, eg "show databases" public bool Parse(ssortingng command) { if (command.IndexOf(" ") == -1) { // No params foreach (ssortingng key in _actionsNoParams.Keys) { if (command == key) { _actionsNoParams[key].Invoke(); return true; } } } else { // Params foreach (ssortingng key in _actions.Keys) { if (command.StartsWith(key) && command.Length > key.Length) { ssortingng options = command.Subssortingng(key.Length); options = options.Trim(); ssortingng[] parts = options.Split(' '); _actions[key].Invoke(parts); return true; } } } return false; } } 

Mon favori personnel est http://www.codeproject.com/KB/recipes/plossum_commandline.aspx par Peter Palotas:

 [CommandLineManager(ApplicationName="Hello World", Copyright="Copyright (c) Peter Palotas")] class Options { [CommandLineOption(Description="Displays this help text")] public bool Help = false; [CommandLineOption(Description = "Specifies the input file", MinOccurs=1)] public ssortingng Name { get { return mName; } set { if (Ssortingng.IsNullOrEmpty(value)) throw new InvalidOptionValueException( "The name must not be empty", false); mName = value; } } private ssortingng mName; } 

J’ai récemment découvert l’implémentation d’parsing de ligne de commande FubuCore que j’apprécie vraiment, les raisons étant:

  • il est facile à utiliser – bien que je ne puisse pas trouver de documentation pour cela, la solution FubuCore fournit également un projet contenant un ensemble de tests unitaires qui parlent plus de la fonctionnalité que n’importe quelle documentation
  • il a une belle conception orientée object, pas de répétition de code ou d’autres choses telles que j’avais l’habitude d’avoir dans mes applications d’parsing de ligne de commande
  • c’est déclaratif: vous écrivez des classes pour les commandes et les ensembles de parameters et vous les décorez avec des atsortingbuts pour définir diverses options (par exemple, nom, description, obligatoire / facultatif)
  • la bibliothèque imprime même un agréable graphique d’utilisation, basé sur ces définitions

Vous trouverez ci-dessous un exemple simple d’utilisation. Pour illustrer l’utilisation, j’ai écrit un utilitaire simple qui a deux commandes: – add (ajoute un object à une liste – un object est composé d’un nom (chaîne), d’une valeur (int) et d’un drapeau booléen) – liste (listes tous les objects actuellement ajoutés)

Tout d’abord, j’ai écrit une classe de commande pour la commande ‘add’:

 [Usage("add", "Adds an object to the list")] [CommandDescription("Add object", Name = "add")] public class AddCommand : FubuCommand { public override bool Execute(CommandInput input) { State.Objects.Add(input); // add the new object to an in-memory collection return true; } } 

Cette commande prend une instance de CommandInput en tant que paramètre, je le définis ensuite:

 public class CommandInput { [RequiredUsage("add"), Description("The name of the object to add")] public ssortingng ObjectName { get; set; } [ValidUsage("add")] [Description("The value of the object to add")] public int ObjectValue { get; set; } [Description("Multiply the value by -1")] [ValidUsage("add")] [FlagAlias("nv")] public bool NegateValueFlag { get; set; } } 

La prochaine commande est “list”, qui est implémentée comme suit:

 [Usage("list", "List the objects we have so far")] [CommandDescription("List objects", Name = "list")] public class ListCommand : FubuCommand { public override bool Execute(NullInput input) { State.Objects.ForEach(Console.WriteLine); return false; } } 

La commande ‘list’ ne prend aucun paramètre, j’ai donc défini une classe NullInput pour ceci:

 public class NullInput { } 

Tout ce qui rest maintenant est de câbler ceci dans la méthode Main (), comme ceci:

  static void Main(ssortingng[] args) { var factory = new CommandFactory(); factory.RegisterCommands(typeof(Program).Assembly); var executor = new CommandExecutor(factory); executor.Execute(args); } 

Le programme fonctionne comme prévu, en imprimant des conseils sur l’utilisation correcte au cas où des commandes seraient invalides:

  ------------------------ Available commands: ------------------------ add -> Add object list -> List objects ------------------------ 

Et un exemple d’utilisation pour la commande ‘add’:

 Usages for 'add' (Add object) add  [-nv] ------------------------------------------------- Arguments ------------------------------------------------- objectname -> The name of the object to add objectvalue -> The value of the object to add ------------------------------------------------- ------------------------------------- Flags ------------------------------------- [-nv] -> Multiply the value by -1 ------------------------------------- 

Powershell Commandlets.

Analyse effectuée par powershell en fonction des atsortingbuts spécifiés sur les commandlets, prise en charge des validations, jeux de parameters, traitement en pipeline, signalement des erreurs, aide, et le meilleur de tous les objects .NET renvoyés à utiliser dans d’autres commandlets.

Quelques liens utiles:

  • Didacticiel de démarrage rapide
  • Guide de programmation sur MSDN
  • Référence de l’espace de noms sur MSDN

C # CLI est une bibliothèque d’parsing des arguments de ligne de commande très simple que j’ai écrite. C’est bien documenté et open source.

Genghis Command Line Parser est peut-être un peu obsolète, mais il est très complet et fonctionne très bien pour moi.

Je suggère la bibliothèque open-source CSharpOptParse . Il parsing la ligne de commande et hydrate un object .NET défini par l’utilisateur avec l’entrée de ligne de commande. Je me tourne toujours vers cette bibliothèque lors de l’écriture d’une application console C #.

Veuillez utiliser le port .net de l’API clie apache commons. Cela fonctionne très bien.

http://sourceforge.net/projects/dotnetcli/

et l’API d’origine pour les concepts et l’introduction

http://commons.apache.org/cli/

Une classe ad hoc très simple d’utilisation pour l’parsing de ligne de commande, qui prend en charge les arguments par défaut.

 class CommandLineArgs { public static CommandLineArgs I { get { return m_instance; } } public ssortingng argAsSsortingng( ssortingng argName ) { if (m_args.ContainsKey(argName)) { return m_args[argName]; } else return ""; } public long argAsLong(ssortingng argName) { if (m_args.ContainsKey(argName)) { return Convert.ToInt64(m_args[argName]); } else return 0; } public double argAsDouble(ssortingng argName) { if (m_args.ContainsKey(argName)) { return Convert.ToDouble(m_args[argName]); } else return 0; } public void parseArgs(ssortingng[] args, ssortingng defaultArgs ) { m_args = new Dictionary(); parseDefaults(defaultArgs ); foreach (ssortingng arg in args) { ssortingng[] words = arg.Split('='); m_args[words[0]] = words[1]; } } private void parseDefaults(ssortingng defaultArgs ) { if ( defaultArgs == "" ) return; ssortingng[] args = defaultArgs.Split(';'); foreach (ssortingng arg in args) { ssortingng[] words = arg.Split('='); m_args[words[0]] = words[1]; } } private Dictionary m_args = null; static readonly CommandLineArgs m_instance = new CommandLineArgs(); } class Program { static void Main(ssortingng[] args) { CommandLineArgs.I.parseArgs(args, "mySsortingngArg=defaultVal;someLong=12"); Console.WriteLine("Arg mySsortingngArg : '{0}' ", CommandLineArgs.I.argAsSsortingng("mySsortingngArg")); Console.WriteLine("Arg someLong : '{0}' ", CommandLineArgs.I.argAsLong("someLong")); } }