Frage

Beim erstellen der Konsole-Anwendungen, die Parameter annehmen, Sie verwenden können die Argumente zu übergeben Main(string[] args).

In der Vergangenheit habe ich einfach indizierte/looped, dass array und ein paar reguläre Ausdrücke zum extrahieren der Werte.Jedoch, wenn die Befehle gelangen komplizierter, die Analyse kann ziemlich hässlich.

Also ich interessiere mich für:

  • Bibliotheken, die Sie verwenden
  • Muster, die Sie verwenden

Übernehmen Sie die Befehle immer befolgen gängige standards wie hier beantwortet.

War es hilfreich?

Lösung

würde ich dringend empfehlen die Verwendung NDesk.Options ( Dokumentation ) und / oder Mono.Options (gleiche API, andere Namespace). Ein Beispiel aus der Dokumentation :

bool show_help = false;
List<string> names = new List<string> ();
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<string> 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;
}

Andere Tipps

Ich mag die Command Line Parser Library ( http://commandline.codeplex.com/ ). Es hat eine sehr einfache und elegante Art und Weise der Parameter über Attribute einrichten:

class Options
{
    [Option("i", "input", Required = true, HelpText = "Input file to read.")]
    public string 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 string GetUsage()
    {
        var usage = new StringBuilder();
        usage.AppendLine("Quickstart Application 1.0");
        usage.AppendLine("Read user manual for usage instructions...");
        return usage.ToString();
    }
}

Die WPF TestApi Bibliothek kommt mit einer der schönsten Befehlszeile Parser für C # Entwicklung. Ich empfehle in sie suchen, von Ivo Manolov Blog auf der 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);

Sieht aus wie jeder hat seine eigene Haustier command-line Parser, Bild ich hatte besser fügen Sie auch meine :).

http://bizark.codeplex.com/

Diese Bibliothek enthält eine command-line parser das initialisieren wird eine Klasse mit den Werten aus der Kommandozeile.Es hat eine Tonne von Funktionen (ich habe den Bau es über viele Jahre).

Aus der Dokumentation...

Command-line parsing in der BizArk framework hat diese key features:

  • Automatische Initialisierung: Eigenschaften der Klasse werden automatisch eingestellt, basierend auf dem command-line arguments.
  • Standard Eigenschaften: Senden Sie einen Wert ohne die Angabe der Namen der Eigenschaft.
  • Konvertierung: Verwendet die leistungsstarke ConvertEx-Klasse auch in BizArk Werte Umgerechnet, um den richtigen Typ.
  • Boolean-flags: Flags können festgelegt werden, indem Sie einfach mit dem argument (ex, /b für true und /b - für false), oder indem Sie den Wert true/false, ja/Nein, etc.
  • Argument-arrays: Fügen Sie einfach mehrere Werte nach den Kommandozeilen-Namen zu setzen, eine Eigenschaft, die als array definiert.Ex /x 1 2 3 füllen Sie x mit dem array { 1, 2, 3 } (vorausgesetzt, x ist definiert als ein array von ganzen zahlen).
  • Befehlszeilen-Aliase: Eine Eigenschaft Unterstützung für mehrere Befehlszeilen-Aliase für es.Für Beispiel, verwendet den alias ?.
  • Namen teilweise Anerkennung: Sie brauchen nicht zu buchstabieren, den vollständigen Namen oder ein alias, der nur Zauber genug für den parser keine Verwechslungen der Eigenschaft/alias von den anderen.
  • ClickOnce Unterstützt: Initialisieren können Eigenschaften auch, wenn Sie angegeben werden, da der query-string in einem URL für ClickOnce bereitgestellte Anwendungen.Die command-line-Initialisierung Methode wird erkannt, wenn es ausgeführt wird, als ClickOnce oder nicht, so dass Sie Ihren code nicht ändern müssen, wenn Sie es verwenden.
  • Erstellt automatisch /?Hilfe: Dies umfasst schöne Formatierung berücksichtigt, dass die Breite der Konsole.
  • Laden/Speichern Kommandozeilen-Argumente zu einer Datei: Dies ist besonders nützlich, wenn Sie mehrere große, komplexe Sätze von Kommandozeilen-Argumente, die Sie ausführen möchten mehrere mal.

Ich schrieb vor einiger Zeit einen C # Kommandozeilen-Argument-Parser. Seine an: http://www.codeplex.com/CommandLineArguments

CLAP (Befehlszeilenargument parser) eine nutzbare API und wunderbar dokumentiert ist. Sie machen eine Methode, die Parameter mit Anmerkungen versehen. https://github.com/adrianaisemberg/CLAP

Es gibt zahlreiche Lösungen für dieses Problem. Für Vollständigkeit und die Alternative zu bieten, wenn jemand, den ich bin, diese Antwort für zwei nützliche Klassen in meinem google-Code-Bibliothek .

Die erste ist Argument, die nur für das Parsen von Kommandozeilen-Parameter verantwortlich ist. Es sammelt Paaren Name-Wert definiert ist durch Schalter ‚/ x: y‘ oder ‚-X = Y‘ und speichert auch eine Liste von ‚unnamed‘ Einträge. Es ist Grund Nutzung rel="nofollow wird hier diskutiert, sieht die Klasse hier .

Der zweite Teil dieser ist die CommandInterpreter welche schafft eine voll funktionsfähige Befehlszeilenanwendung aus Ihrer .Net-Klasse. Als ein Beispiel:

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

Mit dem obigen Beispielcode Sie folgende ausführen können:

  

Program.exe DoSomething "string" 5

- oder -

  

Program.exe dosomething / iValue = 5 -svalue: "string value"

Es ist so einfach wie das, oder so komplex wie Sie es brauchen. Sie können den Quellcode zu überprüfen, sehen die Hilfe oder laden Sie die binäre .

Ich mag dass ein , weil Sie „definieren Regeln“ für die Argumente, benötigt oder nicht, ...

oder wenn Sie einen Unix-Typ sind, als Sie die GNU Getopt .NET Port .

Sie können gerne meine ein Rug.Cmd

Einfach zu bedienen und erweiterbare Befehlszeilenargument Parser. Griffe: Bool, Plus / Minus, String, String-Liste, CSV, Enumeration.

in Built '/?' Hilfemodus.

gebaut '/ ??' und '/? D' Dokumenten-Generator-Modus.

static void Main(string[] args) 
{            
    // create the argument parser
    ArgumentParser parser = new ArgumentParser("ArgumentExample", "Example of argument parsing");

    // create the argument for a string
    StringArgument StringArg = new StringArgument("String", "Example string argument", "This argument demonstrates string arguments");

    // add the argument to the parser 
    parser.Add("/", "String", StringArg);

    // parse arguemnts
    parser.Parse(args);

    // did the parser detect a /? argument 
    if (parser.HelpMode == false) 
    {
        // was the string argument defined 
        if (StringArg.Defined == true)
        {
            // write its value
            RC.WriteLine("String argument was defined");
            RC.WriteLine(StringArg.Value);
        }
    }
}

Edit: Das ist mein Projekt und als solche diese Antwort sollte nicht als Befürwortung von Dritten eingesehen werden. Das sagte ich es verwenden für jede Befehlszeile basiertes Programm, ich schreibe, es ist Open Source und es ist meine Hoffnung, dass andere können davon profitieren.

Es ist ein Kommandozeilenargument Parser unter http://www.codeplex.com/commonlibrarynet

Es kann Argumente analysieren mit
1. Attribute
2. expliziten Anrufe
3. einzige Zeile mehr Argumente oder String-Array

Es kann Dinge behandeln wie folgt aus:

- Konfiguration : Qa - startdate : $ { heute } - Region : 'New York' Settings01

Es ist sehr einfach zu bedienen.

Dies ist ein Handler I basierend auf der Novell Options Klasse geschrieben.

Dieser ist bei Konsolenanwendungen ausgerichtet, die eine while (input !="exit") Stil Schleife, eine interaktive Konsole wie eine FTP-Konsole zum Beispiel auszuführen.

Beispiel Nutzung:

static void Main(string[] 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(">");
    string input = System.Console.ReadLine();

    while (input != "quit" && input != "exit")
    {
        if (input == "cls" || input == "clear")
        {
            System.Console.Clear();
        }
        else
        {
            if (!string.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();
    }
}

Und die Quelle:

/// <summary>
/// A class for parsing commands inside a tool. Based on Novell Options class (http://www.ndesk.org/Options).
/// </summary>
public class CommandOptions
{
    private Dictionary<string, Action<string[]>> _actions;
    private Dictionary<string, Action> _actionsNoParams;

    /// <summary>
    /// Initializes a new instance of the <see cref="CommandOptions"/> class.
    /// </summary>
    public CommandOptions()
    {
        _actions = new Dictionary<string, Action<string[]>>();
        _actionsNoParams = new Dictionary<string, Action>();
    }

    /// <summary>
    /// Adds a command option and an action to perform when the command is found.
    /// </summary>
    /// <param name="name">The name of the command.</param>
    /// <param name="action">An action delegate</param>
    /// <returns>The current CommandOptions instance.</returns>
    public CommandOptions Add(string name, Action action)
    {
        _actionsNoParams.Add(name, action);
        return this;
    }

    /// <summary>
    /// Adds a command option and an action (with parameter) to perform when the command is found.
    /// </summary>
    /// <param name="name">The name of the command.</param>
    /// <param name="action">An action delegate that has one parameter - string[] args.</param>
    /// <returns>The current CommandOptions instance.</returns>
    public CommandOptions Add(string name, Action<string[]> action)
    {
        _actions.Add(name, action);
        return this;
    }

    /// <summary>
    /// Parses the text command and calls any actions associated with the command.
    /// </summary>
    /// <param name="command">The text command, e.g "show databases"</param>
    public bool Parse(string command)
    {
        if (command.IndexOf(" ") == -1)
        {
            // No params
            foreach (string key in _actionsNoParams.Keys)
            {
                if (command == key)
                {
                    _actionsNoParams[key].Invoke();
                    return true;
                }
            }
        }
        else
        {
            // Params
            foreach (string key in _actions.Keys)
            {
                if (command.StartsWith(key) && command.Length > key.Length)
                {

                    string options = command.Substring(key.Length);
                    options = options.Trim();
                    string[] parts = options.Split(' ');
                    _actions[key].Invoke(parts);
                    return true;
                }
            }
        }

        return false;
    }
}

Mein persönlicher Favorit ist http://www.codeproject.com/KB/recipes/ plossum_commandline.aspx von 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 string Name
   {
      get { return mName; }
      set
      {
         if (String.IsNullOrEmpty(value))
            throw new InvalidOptionValueException(
                "The name must not be empty", false);
         mName = value;
      }
   }

   private string mName;
}

Ich kam vor kurzem über die FubuCore Befehlszeile Parsen Implementierung Ich mag es, die Gründe dafür sind:

  • es ist einfach zu bedienen - auch wenn ich nicht eine Dokumentation dafür, die FubuCore Lösung stellt auch ein Projekt, das eine schöne Reihe von Unit-Tests, die mehr über die Funktionalität als jede Dokumentation sprechen finden konnte, konnte
  • es hat ein nettes objektorientiertes Design, keinen Code Wiederholung oder andere solche Dinge, die ich verwenden in meinem Kommandozeile Parsing-Anwendungen haben
  • es ist deklarative: Sie grundsätzlich schreiben Klassen für die Befehle und Parametersätze und schmücken sie mit Attributen verschiedene Optionen (z Name, Beschreibung, obligatorisch / optional)
  • einstellen
  • druckt die Bibliothek auch eine schöne Nutzungs Grafik, auf der Grundlage dieser Definitionen

Im Folgenden ist ein einfaches Beispiel dafür, wie diese zu verwenden. Um die Verwendung zu erläutern, habe ich ein einfaches Programm geschrieben, das zwei Befehle hat: - add (fügt ein Objekt in einer Liste - Ein Objekt besteht aus einem Namen (string), Wert (int) und eine Boolesche Flag) - Liste (listet alle aktuell hinzugefügten Objekte)

Zunächst einmal ich eine Befehlsklasse für den ‚add‘ Befehl schrieb:

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

        return true;
    }
}

Dieser Befehl nimmt eine CommandInput Instanz als Parameter, so definiere ich, dass nächste:

public class CommandInput
{
    [RequiredUsage("add"), Description("The name of the object to add")]
    public string 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; }
}

Der nächste Befehl ist ‚Liste‘, die implementiert ist wie folgt:

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

        return false;
    }
}

Die ‚Liste‘ Befehl übernimmt keine Parameter, so definierte ich eine NullInput Klasse für diese:

public class NullInput { }

, dass jetzt alle bleibt, ist dies in der Methode Main () verkabeln, wie folgt aus:

    static void Main(string[] args)
    {
        var factory = new CommandFactory();
        factory.RegisterCommands(typeof(Program).Assembly);

        var executor = new CommandExecutor(factory);

        executor.Execute(args);
    }

Das Programm funktioniert wie erwartet, Druck Hinweise über die korrekte Nutzung im Falle irgendwelche Befehle sind ungültig:

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

Und ein Verwendungsbeispiel für den 'add' Befehl:

Usages for 'add' (Add object)
  add <objectname> [-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.

Parsing von Powershell getan basierend auf Attribute auf dem Commandlets angegeben, Unterstützung für Validierungen, Parametersätze, Pipelining, Fehlerberichterstattung, Hilfe und besten alles Rückkehr .NET-Objekte für die Verwendung in anderen Commandlets.

Ein paar Links fand ich hilfreich ersten Schritte:

C # CLI ist eine sehr einfache Befehlszeilenargument Parsing-Bibliothek, die ich geschrieben habe. Es ist gut dokumentiert und Open Source.

Dschingis Command Line Parser ein wenig veraltet sein können, aber es ist sehr verfügen über vollständige und funktioniert recht gut für mich.

Ich würde vorschlagen, die Open-Source-Bibliothek CSharpOptParse . Es analysiert die Befehlszeile und Hydrate ein benutzerdefiniertes NET-Objekts mit der Befehlszeileneingabe. Ich drehe ich immer auf diese Bibliothek, wenn eine C # Konsolenanwendung zu schreiben.

Bitte benutzen Sie den .net-Port des Apache Commons cli API. Dies funktioniert gut.

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

und die ursprüngliche API für Konzepte und Einführung

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

Ein sehr einfach einfach zu bedienen Ad-hoc-Klasse für das Parsen Befehlszeile, die das Standard Argument unterstützt.

class CommandLineArgs
{
    public static CommandLineArgs I
    {
        get
        {
            return m_instance;
        }
    }

    public  string argAsString( string argName )
    {
        if (m_args.ContainsKey(argName)) {
            return m_args[argName];
        }
        else return "";
    }

    public long argAsLong(string argName)
    {
        if (m_args.ContainsKey(argName))
        {
            return Convert.ToInt64(m_args[argName]);
        }
        else return 0;
    }

    public double argAsDouble(string argName)
    {
        if (m_args.ContainsKey(argName))
        {
            return Convert.ToDouble(m_args[argName]);
        }
        else return 0;
    }

    public void parseArgs(string[] args, string defaultArgs )
    {
        m_args = new Dictionary<string, string>();
        parseDefaults(defaultArgs );

        foreach (string arg in args)
        {
            string[] words = arg.Split('=');
            m_args[words[0]] = words[1];
        }
    }

    private void parseDefaults(string defaultArgs )
    {
        if ( defaultArgs == "" ) return;
        string[] args = defaultArgs.Split(';');

        foreach (string arg in args)
        {
            string[] words = arg.Split('=');
            m_args[words[0]] = words[1];
        }
    }

    private Dictionary<string, string> m_args = null;
    static readonly CommandLineArgs m_instance = new CommandLineArgs();
}

class Program
{
    static void Main(string[] args)
    {
        CommandLineArgs.I.parseArgs(args, "myStringArg=defaultVal;someLong=12");
        Console.WriteLine("Arg myStringArg  : '{0}' ", CommandLineArgs.I.argAsString("myStringArg"));
        Console.WriteLine("Arg someLong     : '{0}' ", CommandLineArgs.I.argAsLong("someLong"));
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top