Madgnome's lair

Adapted by Julien Hoarau

Lorsque l’on développe une application console, on se retrouve rapidement confronté au problème de la gestion des arguments passés au démarrage. Et étonnement il n’y a rien dans le framework .NET pour gérer cela (une rumeur prévoyait cela pour .NET 4, mais il n’en est rien au final). On a donc le choix entre partir vers une solution faite maison : “Après tout, je n’ai besoin que de deux paramètres… trois… quatre grands maximums” et l’on se retrouve à fouiner dans le code au bout de deux semaines car l’on avait jugé inutile d’inclure l’aide (“pour deux paramètres à quoi bon!”).

L’autre solution est bien évidemment d’utiliser une librairie, parmi les nombreuses disponibles. Je vais dans ce billet en présenter trois :

Mono.GetOptions :

Il faut d’abord récupérer Mono, et l’installer. Vous pourrez alors référencer la librairie Mono.GetOptions.dll dans votre programme et commencer à l’utiliser.

Déclaration des arguments (par le biais d’attributs):

using Mono.GetOptions;

namespace CommandLineParserTest.Mono.GetOptions
{
  public class CommandLineArgumentOptions : Options
  {
    // Option(ShortDescription, ShortForm)
    // Long option is the variable name ("--logFile"), short option is -l
    [Option("Write logFile to FILE", ShortForm = 'l')] 
    public string logFile;

    [Option("Toggle verbose mode", 'v')] 
    public bool verbose;

    public CommandLineArgumentOptions()
    {
      ParsingMode = OptionsParsingMode.Both;
    }
  }
}

Parsing des arguments :

namespace CommandLineParserTest.Mono.GetOptions
{
  internal class Program
  {
    private static void Main(string[] args)
    {
      CommandLineArgumentOptions options = new CommandLineArgumentOptions();
      options.ProcessArgs(args);

      Console.WriteLine("Specified Program Options:");
      Console.WriteLine("logFile: {0}", options.logFile);
      Console.WriteLine("verbose: {0}", options.verbose);
    }
  }
}

NDesk.Options :

Actuellement, il n’y a pas encore de livrable prêt à l’emploi pour NDesk.Options, il faut donc télécharger les sources et le construire (d’après le site de NDesk il y a un binaire quelque part, mais je n’ai pas réussi à mettre la main dessus). Vous pouvez sinon ajouter directement le fichier NDesk.Options/Options.cs à votre projet.

Déclaration des arguments à la C# 3.0 (lambda, mais il est possible d’utiliser des delegates pour une compatibilité C# 2.0):

string logFile;
bool verbose;
bool help = false;

var commandLineArgumentOptions =
  new OptionSet()
    {
      {
        "l|logFile=",
        "Write logFile to FILE",
        v => logFile = v
      },
      {
        "v|verbose",
        "Toggle verbose mode",
        v => verbose = (v != null)
      }, 
      {
        "h|help", 
        "Show this message and exit", 
        v => help = (v != null)
      }
    };

Parsing des arguments :

try
{
  commandLineArgumentOptions.Parse(args);
}
catch (OptionException e)
{
  Console.WriteLine(e.Message);
  Console.WriteLine("Try 'program.exe --help' for more information.");
  return;
}

if (help)
{
  commandLineArgumentOptions.WriteOptionDescriptions(Console.Out);
}

Command Line Parser Library :

Télécharger. Dézipper. Référencer la librairie CommandLine.dll, on a là notre gagnant en terme de rapidité et de simplicité d’installation.

Déclaration des arguments (par le biais d’attributs) :

private sealed class CommandLineArgumentOptions
{
  [Option("l", "logFile", Required = true, HelpText = "Write logFile to FILE")] 
  public string LogFile;

  [Option("v", "verbose", Required = false, HelpText = "Toggle verbose mode")] 
  public bool Verbose;

  [HelpOption(HelpText = "Show this message and exit")]
  public string GetUsage()
  {
    HelpText help = new HelpText(Program.headingInfo);
    help.Copyright = new CopyrightInfo("Julien Hoarau", 2009, 2014);

    help.AddOptions(this);

    return help;
  }
}

Parsing des arguments :

private static void Main(string[] args)
{
  CommandLineArgumentOptions commandLineArguments = 
    new CommandLineArgumentOptions();
  ICommandLineParser parser = 
    new CommandLine.CommandLineParser();

  if(parser.ParseArguments(args, commandLineArguments, Console.Error))
  {
    Console.WriteLine("Specified Program Options:");
    Console.WriteLine("logFile: {0}", commandLineArguments.LogFile);
    Console.WriteLine("verbose: {0}", commandLineArguments.Verbose);
  }
}

Bilan

On retrouve les mêmes fonctionnalités principales dans les 3, il s’agit après d’une question de goût.
Mono.GetOptions et Command Line Parsing Library partagent un mode de déclaration par attributs, plus adapté pour cette situation, à mon sens, que la méthode de NDesk.Options à base de lambdas.

A choisir entre Mono.GetOptions et Command Line Parsing Library, mon choix se porterait sur Command Line Parsing Library, qui a l’avantage de ne pas être marqué comme obsolète et qui est plus simple à récupérer.

(0) Comments

Enregistrer un commentaire