731 Stimmen

Beste Weg, um Befehlszeilenargumente in C# zu parsen?

Wenn Sie Konsolenanwendungen erstellen, die Parameter benötigen, können Sie die Argumente verwenden, die an Main(string[] args) .

In der Vergangenheit habe ich einfach indiziert/geschleift, dass Array und tat ein paar reguläre Ausdrücke, um die Werte zu extrahieren. Wenn die Befehle jedoch komplizierter werden, kann das Parsing ziemlich unschön werden.

Ich bin also interessiert:

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

Gehen Sie davon aus, dass sich die Befehle immer an gemeinsame Standards halten, wie z. B. hier beantwortet .

0 Stimmen

Eine frühere Diskussion, split-string-enthalten-kommandozeilen-parameter-in-string-in-c# hat vielleicht einige Antworten.

1 Stimmen

Hallo, tut mir leid, es ist ein bisschen off-topic. aber ich benutze die "Anwendungseinstellungen", um Argumente an die Anwendung zu übergeben. Ich fand es ziemlich einfach zu bedienen und keine Notwendigkeit, Argument/Datei-Parsing zu schreiben, und keine Notwendigkeit für zusätzliche Bibliothek. msdn.microsoft.com/de-us/library/aa730869(VS.80).aspx

44 Stimmen

@call me Steve: Der Sinn von Kommandozeilenargumenten ist, dass sie bei jedem Aufruf variieren können - wie machen Sie das mit den Anwendungseinstellungen?

2voto

Chris S Punkte 63542

Dies ist ein Handler, den ich auf der Grundlage des Novell Options Klasse.

Diese richtet sich an Konsolenanwendungen, die eine while (input !="exit") Schleife, eine interaktive Konsole wie z. B. eine FTP-Konsole.

Beispiel für die Verwendung:

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;
    }
}

1voto

devdimi Punkte 2412

Dschingis Kommandozeilen-Parser ist vielleicht ein wenig veraltet, aber es hat viele Funktionen und funktioniert für mich sehr gut.

0 Stimmen

Traurig, aber Genghis Command Line Parser hat keine Dokumentation.

0 Stimmen

In den Quellen finden Sie ein Beispiel, das die Verwendungsmöglichkeiten aufzeigt. genghis.codeplex.com/SourceControl/changeset/view/9491#73699

0voto

Andreas Punkte 699

Bitte verwenden Sie den .net-Port der Apache Commons Cli API. Das funktioniert hervorragend.

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

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

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

0voto

Martin Lütken Punkte 21

Eine sehr einfache, leicht zu verwendende Ad-hoc-Klasse zum Parsen von Befehlszeilen, die Standardargumente 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"));
    }
}

0voto

Stuart Lange Punkte 3959

Ich würde die Open-Source-Bibliothek CSharpOptParse . Sie analysiert die Befehlszeile und verknüpft ein benutzerdefiniertes .NET-Objekt mit der Befehlszeileneingabe. Ich greife immer auf diese Bibliothek zurück, wenn ich eine C#-Konsolenanwendung schreibe.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X