أفضل طريقة لتحليل وسيطات سطر الأوامر في C# ؟ [مغلقة]

StackOverflow https://stackoverflow.com/questions/491595

  •  20-08-2019
  •  | 
  •  

سؤال

عند بناء تطبيقات وحدة التحكم التي تأخذ المعلمات يمكنك استخدام الحجج التي مرت على Main(string[] args).

في الماضي كنت ببساطة فهرسة/يحلق أن مجموعة فعلت بعض التعبيرات العادية لاستخراج القيم.ومع ذلك ، عندما الأوامر الحصول على أكثر تعقيدا ، تحليل يمكن الحصول على قبيح جدا.

لذلك أنا مهتم في:

  • المكتبات التي تستخدمها
  • أنماط استخدام

نفترض الأوامر تلتزم دائما إلى معايير مشتركة مثل الإجابة هنا.

هل كانت مفيدة؟

المحلول

أود أن أقترح بشدة باستخدام NDesk.خيارات (الوثائق) و/أو أحادية.خيارات (نفس API, مساحة مختلفة).وهو مثال من وثائق:

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

نصائح أخرى

أنا حقا أحب سطر الأوامر محلل مكتبة ( http://commandline.codeplex.com/ ).وقد بسيطة جدا وأنيقة طريقة إعداد المعلمات عبر سمات:

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

على WPF TestApi المكتبة يأتي مع واحدة من اجمل سطر الأوامر موزعي C# التنمية.أنا أوصي به من إيفو Manolov بلوق على 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);

يبدو أن الجميع لديه الحيوانات الأليفة الخاصة بهم سطر الأوامر موزعي, الرقم كان أفضل إضافة لي كذلك :).

http://bizark.codeplex.com/

هذه المكتبة تحتوي على سطر الأوامر محلل التي من شأنها تهيئة فئة مع القيم من سطر الأوامر.وقد طن من الميزات (لقد تم بناء ذلك على مدى سنوات عديدة).

من الوثائق...

سطر الأوامر تحليل في BizArk إطار هذه الميزات الرئيسية:

  • التلقائي التهيئة: خصائص الطبقة تلقائيا استنادا إلى وسائط سطر الأوامر.
  • الخصائص الافتراضية: إرسال القيمة دون تحديد اسم الخاصية.
  • قيمة التحويل: يستخدم قوية ConvertEx الطبقة أيضا في BizArk لتحويل القيم إلى النوع المناسب.
  • منطقية الأعلام: أعلام يمكن تحديدها ببساطة عن طريق استخدام الحجة (السابق /b الحقيقي و /ب - خطأ) أو عن طريق إضافة قيمة true/false ، نعم/لا.... الخ
  • حجة المصفوفات: ببساطة إضافة قيم متعددة بعد سطر الأوامر على الممتلكات التي يتم تعريف صفيف.السابق /x 1 2 3 سيتم ملء x مع مجموعة { 1, 2, 3 } (على افتراض x بأنها مجموعة من الاعداد الصحيحه).
  • سطر الأوامر الأسماء المستعارة: خاصية دعم متعددة سطر الأوامر الأسماء المستعارة لذلك.على سبيل المثال ، تساعد يستخدم المستعار؟.
  • الاسم الجزئي الاعتراف: أنت لا تحتاج إلى توضيح الاسم الكامل أو اسم مستعار, مجرد توضيح ما يكفي محلل إلى إزالة الغموض عن الملكية/الاسم المستعار من الآخرين.
  • يدعم ClickOnce: يمكن تهيئة خصائص حتى عندما يتم تحديد سلسلة الاستعلام في URL ClickOnce نشر التطبيقات.سطر الأوامر أسلوب التهيئة سيتم الكشف عن إذا كان يعمل كما ClickOnce أو حتى التعليمات البرمجية الخاصة بك لا تحتاج إلى تغيير عند استخدامه.
  • تلقائيا بإنشاء /?مساعدة: وهذا يشمل تنسيق جميل أن يأخذ في الاعتبار العرض من وحدة التحكم.
  • تحميل/حفظ سطر الأوامر إلى ملف: هذا هو مفيدة بشكل خاص إذا كان لديك عدة كبيرة, مجموعات معقدة من سطر الأوامر التي كنت ترغب في تشغيل عدة مرات.

كتبت C# وسيطة سطر الأوامر محلل في حين يعود.لها في: http://www.codeplex.com/CommandLineArguments

التصفيق (وسيطة سطر الأوامر محلل) وقد صالحة للاستعمال API و رائعة موثقة.يمكنك جعل طريقة التأشير المعلمات. https://github.com/adrianaisemberg/CLAP

هناك العديد من الحلول لهذه المشكلة.عن اكتمال وتوفير البديل إذا كان هناك شخص يرغب أنا مضيفا ان هذا الجواب عن اثنين من فئات مفيدة في بلدي مدونة جوجل المكتبة.

الأول هو ArgumentList الذي هو المسؤول الوحيد عن توزيع معلمات سطر الأوامر.تجمعها اسم أزواج قيمة يحددها مفاتيح '/x:y' أو '-x=y' و أيضا بجمع قائمة 'اسمه' الإدخالات.انها الأساسية استخدام مناقشتها هنا, عرض الدرجة هنا.

الجزء الثاني من هذا CommandInterpreter مما يخلق وظيفية بالكامل تطبيق سطر الأوامر الخاص بك .صافي الدرجة.كمثال:

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)
        { ... }

مع المثال أعلاه رمز يمكنك تشغيل التالية:

Program.exe DoSomething "قيمة سلسلة" 5

- أو -

Program.exe dosomething /ivalue=5 -svalue:"سلسلة القيمة"

انها بسيطة على هذا النحو أو معقدة كما تحتاج لها أن تكون.يمكنك مراجعة التعليمات البرمجية المصدر, عرض المساعدة, أو تحميل الثنائية.

أحب هذا واحد, لأنك يمكن أن "تحديد قواعد" عن الحجج اللازمة أم لا ، ...

أو إذا كنت Unix الرجل ، مما قد تحب غنو Getopt .صافي الميناء.

قد كنت مثل بلدي واحد البساط.Cmd

سهلة الاستخدام و قابلة للتوسيع وسيطة سطر الأوامر محلل.مقابض:منطقي, زائد / ناقص, سلسلة, سلسلة قائمة ، CSV ، التعداد.

بنيت في '/?' مساعدة الوضعية.

بنيت في '/??' و '/?د' الوثيقة مولد وسائط.

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

تحرير:هذا هو بلدي مشروع مثل هذا الجواب لا ينبغي أن ينظر إليه على أنه تأييد من طرف ثالث.وقال أن أفعل استخدامه في كل سطر الأوامر على أساس برنامج أكتب مفتوح المصدر وآمل أن الآخرين قد تستفيد من ذلك.

هناك وسيطة سطر الأوامر محلل في http://www.codeplex.com/commonlibrarynet

فإنه يمكن تحليل الحجج باستخدام
1.سمات
2.صراحة المكالمات
3.سطر واحد من حجج متعددة أو صفيف سلسلة

فإنه يمكن التعامل مع أشياء مثل التالية:

-التكوين:سؤال وجواب -startdate:${اليوم} -المنطقة:'نيويورك' Settings01

فإنه من السهل جدا للاستخدام.

هذا هو معالج كتبت بناء على Novell Options فئة.

هذا هو واحد التي تهدف إلى التحكم في التطبيقات التي تنفيذ while (input !="exit") نمط حلقة تفاعلية وحدة مثل FTP التحكم على سبيل المثال.

مثال على الاستخدام:

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

المصدر:

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

قناعتي الشخصية المفضلة هي http://www.codeproject.com/KB/recipes/plossum_commandline.aspx بواسطة بيتر 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;
}

كنت مؤخرا قد جاء عبر FubuCore سطر الأوامر تحليل التنفيذ أنا حقا مثل ذلك ، فإن الأسباب:

  • انها سهلة الاستخدام - على الرغم من أنني لم أتمكن من العثور على وثائق ، FubuCore الحل كما يوفر المشروع يحتوي على مجموعة لطيفة من وحدة الاختبارات التي تتحدث أكثر عن الوظائف من أي وثائق يمكن أن
  • لديها لطيفة وجوه المنحى والتصميم لا يوجد قانون التكرار أو غيرها من الأشياء التي اعتدت أن يكون في سطر الأوامر تحليل تطبيقات
  • إنه التعريفي:كنت في الأساس كتابة فصول الأوامر مجموعات من المعلمات وتزيين لهم مع سمات تعيين خيارات مختلفة (مثلا ، الاسم والوصف إلزامية/اختياري)
  • المكتبة حتى يطبع لطيفة استخدام الرسم البياني ، استنادا إلى هذه التعاريف ،

أدناه هو مثال بسيط على كيفية استخدام هذا.لتوضيح الاستخدام ، لقد كتبت أداة بسيطة التي الأمرين:- إضافة (يضيف كائن إلى قائمة كائن يتكون من اسم(سلسلة) ، قيمة(الباحث) و منطقية العلم) - قائمة (قائمة بجميع حاليا الكائنات المضافة)

أولا أنا كتبت قيادة الطبقة من أجل إضافة الأوامر:

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

هذا الأمر يأخذ CommandInput سبيل المثال كما المعلمة لذا تحديد التالي:

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

الأمر التالي هو قائمة ، والتي يتم تنفيذها على النحو التالي:

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

'قائمة' الأمر لا يأخذ المعلمات ، لذا عرف NullInput الطبقة عن هذا:

public class NullInput { }

كل ما تبقى الآن هو أن سلك هذا في طريقة الرئيسي() مثل هذا:

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

        var executor = new CommandExecutor(factory);

        executor.Execute(args);
    }

البرنامج يعمل كما هو متوقع ، الطباعة تلميحات حول الاستخدام الصحيح في حالة أية أوامر غير صحيحة:

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

و عينة الاستخدام من أجل إضافة الأوامر:

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.

تحليل قام به powershell على أساس الصفات المحددة على commandlets ، ودعم التصديقات, المعلمة مجموعات ، pipelining, عن الخطأ, مساعدة, وأفضل من جميع العائدين .صافي الكائنات في commandlets.

عدة روابط وجدت من المفيد البدء:

C# CLI هو بسيط جدا وسيطة سطر الأوامر تحليل المكتبة التي كتبت.انها موثقة و مفتوحة المصدر.

جنكيز سطر الأوامر محلل قد يكون قليلا من التاريخ ، ولكن هناك ميزة كاملة يعمل بشكل جيد جدا بالنسبة لي.

أود أن أقترح مفتوحة المصدر مكتبة CSharpOptParse.فإنه يوزع سطر الأوامر و هيدرات المعرفة من قبل المستخدم .صافي كائن مع سطر الإدخال.أنا دائما اللجوء إلى هذه المكتبة عند كتابة C# تطبيق وحدة التحكم.

الرجاء استخدام .صافي ميناء أباتشي العموم cli API.هذا يعمل كبيرة.

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

الأصلي API المفاهيم مقدمة

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

بسيطة جدا وسهلة الاستخدام المخصص لفئة سطر الأوامر تحليل, الذي يدعم الافتراضي الحجج.

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"));
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top