c# सी#में कमांड लाइन तर्कों का विश्लेषण करने का सबसे अच्छा तरीका?




.net command-line-arguments (16)

पैरामीटर लेने वाले कंसोल अनुप्रयोगों का निर्माण करते समय, आप Main(string[] args) तर्क) को पारित तर्कों का उपयोग कर सकते हैं।

अतीत में मैंने बस उस सरणी को अनुक्रमित / लूप किया है और मान निकालने के लिए कुछ नियमित अभिव्यक्तियां की हैं। हालांकि, जब आदेश अधिक जटिल हो जाते हैं, तो पार्सिंग बहुत बदसूरत हो सकती है।

तो मुझे इसमें दिलचस्पी है:

  • पुस्तकालय जो आप उपयोग करते हैं
  • पैटर्न जो आप उपयोग करते हैं

मान लें कि आदेश हमेशा सामान्य मानकों का पालन करते हैं जैसे कि यहां उत्तर दिया गया है


डब्ल्यूपीएफ टेस्टएपी लाइब्रेरी सी # विकास के लिए सबसे अच्छे कमांड लाइन पार्सर्स में से एक के साथ आता है। एपीआई पर इवो मनोलोव के ब्लॉग से, मैं अत्यधिक इसकी अनुशंसा करता हूं:

// 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://www.codeplex.com/commonlibrarynet पर एक कमांड लाइन तर्क पार्सर है

यह तर्क का उपयोग कर विश्लेषण कर सकते हैं
1. गुण
2. स्पष्ट कॉल
3. एकाधिक तर्कों या स्ट्रिंग सरणी की एकल पंक्ति

यह निम्नलिखित की तरह चीजों को संभाल सकता है:

- कॉन्फ़िगरेशन : क्यूए - स्टार्टडेट : $ { आज } - क्षेत्र : 'न्यूयॉर्क' सेटिंग्स 01

इसका उपयोग करना बहुत आसान है।


सी # सीएलआई एक बहुत ही सरल कमांड लाइन तर्क पार्सिंग लाइब्रेरी है जिसे मैंने लिखा था। यह अच्छी तरह से प्रलेखित और खुला स्रोत है।



मैं हाल ही में द फुबकोर कमांड लाइन पार्सिंग कार्यान्वयन में आया था, मुझे वास्तव में यह पसंद है, कारण हैं:

  • इसका उपयोग करना आसान है - हालांकि मुझे इसके लिए कोई प्रलेखन नहीं मिला, FubuCore समाधान भी एक परियोजना प्रदान करता है जिसमें यूनिट टेस्ट का एक अच्छा सेट होता है जो किसी भी दस्तावेज की तुलना में कार्यक्षमता के बारे में अधिक बोल सकता है
  • इसमें एक अच्छा ऑब्जेक्ट उन्मुख डिज़ाइन है, कोई कोड पुनरावृत्ति या ऐसी अन्य चीजें जिन्हें मैं अपने कमांड लाइन पार्सिंग ऐप्स में उपयोग करता था
  • यह घोषणात्मक है: आप मूल रूप से कमांड और पैरामीटर के सेट के लिए कक्षाएं लिखते हैं और विभिन्न विकल्पों को सेट करने के लिए उन्हें विशेषताओं के साथ सजाते हैं (जैसे नाम, वर्णन, अनिवार्य / वैकल्पिक)
  • लाइब्रेरी इन परिभाषाओं के आधार पर एक अच्छा उपयोग ग्राफ प्रिंट भी करती है

इसका उपयोग करने के तरीके के बारे में नीचे एक सरल उदाहरण है। उपयोग को चित्रित करने के लिए, मैंने एक सरल उपयोगिता लिखी है जिसमें दो आदेश हैं: - जोड़ें (किसी ऑब्जेक्ट को किसी सूची में जोड़ता है - किसी ऑब्जेक्ट में एक नाम (स्ट्रिंग), मान (int) और एक बूलियन ध्वज होता है) - सूची (सूचियां वर्तमान में सभी जोड़े गए ऑब्जेक्ट्स)

सबसे पहले, मैंने 'एड' कमांड के लिए कमांड क्लास लिखा था:

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

यह आदेश पैरामीटर के रूप में कमांड इनपुट उदाहरण लेता है, इसलिए मैं इसे परिभाषित करता हूं:

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

CLAP (कमांड लाइन तर्क पार्सर) में एक प्रयोग योग्य एपीआई है और यह अद्भुत दस्तावेज है। आप पैरामीटर को एनोटेट करते हुए एक विधि बनाते हैं। https://github.com/adrianaisemberg/CLAP



पीटर पलोटास द्वारा मेरा व्यक्तिगत पसंदीदा http://www.codeproject.com/KB/recipes/plossum_commandline.aspx है:

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

मुझे वह पसंद है , क्योंकि आप तर्कों के लिए "नियम परिभाषित कर सकते हैं", आवश्यक या नहीं, ...

या यदि आप यूनिक्स लड़के हैं, तो आप जीएनयू गेटोपेट .NET पोर्ट को पसंद कर सकते हैं।


ऐसा लगता है कि हर किसी के पास अपने पालतू कमांड लाइन पार्सर्स हैं, आंकड़े मैंने बेहतर रूप से मेरा भी जोड़ा था :)।

http://bizark.codeplex.com/

इस पुस्तकालय में एक कमांड लाइन पार्सर है जो कमांड लाइन से मानों के साथ कक्षा को प्रारंभ करेगा। इसमें कई टन विशेषताएं हैं (मैं इसे कई वर्षों से बना रहा हूं)।

दस्तावेज से ...

बिज़एर्क फ्रेमवर्क में कमांड लाइन पार्सिंग में इन प्रमुख विशेषताएं हैं:

  • स्वचालित प्रारंभिकरण: कक्षा गुण स्वचालित रूप से कमांड-लाइन तर्कों के आधार पर सेट होते हैं।
  • डिफ़ॉल्ट गुण: संपत्ति नाम निर्दिष्ट किए बिना मूल्य में भेजें।
  • मूल्य रूपांतरण: मूल्यों को उचित प्रकार में बदलने के लिए BizArk में शक्तिशाली कनवर्टएक्स क्लास भी शामिल है।
  • बूलियन झंडे: झंडे को केवल तर्क (पूर्व, / बी के लिए सत्य और / b- झूठी) का उपयोग करके निर्दिष्ट किया जा सकता है या मान को सही / गलत, हां / नहीं, आदि जोड़कर निर्दिष्ट किया जा सकता है।
  • Argument arrays: किसी सरणी के रूप में परिभाषित संपत्ति को सेट करने के लिए कमांड-लाइन नाम के बाद बस कई मान जोड़ें। पूर्व, / x 1 2 3 सरणी {1, 2, 3} के साथ एक्स को पॉप्युलेट करेगा (माना जाता है कि x को पूर्णांक की सरणी के रूप में परिभाषित किया गया है)।
  • कमांड लाइन उपनाम: एक संपत्ति इसके लिए एकाधिक कमांड लाइन उपनाम का समर्थन कर सकती है। उदाहरण के लिए, सहायता उपनाम का उपयोग करता है?
  • आंशिक नाम पहचान: आपको पूर्ण नाम या उपनाम का स्पेल करने की आवश्यकता नहीं है, केवल पार्सर को अन्य लोगों से संपत्ति / उपनाम को असंबद्ध करने के लिए पर्याप्त वर्तनी करें।
  • ClickOnce का समर्थन करता है: क्लिकऑन परिनियोजित अनुप्रयोगों के लिए URL में क्वेरी स्ट्रिंग के रूप में निर्दिष्ट होने पर भी गुणों को प्रारंभ कर सकते हैं। कमांड लाइन प्रारंभिक विधि यह पता लगाएगी कि यह क्लिकऑन के रूप में चल रहा है या नहीं, इसलिए इसका उपयोग करते समय आपके कोड को बदलने की आवश्यकता नहीं है।
  • स्वचालित रूप से बनाता है /? सहायता: इसमें अच्छी स्वरूपण शामिल है जो कंसोल की चौड़ाई को ध्यान में रखती है।
  • किसी फ़ाइल में कमांड-लाइन तर्क लोड / सहेजें: यह विशेष रूप से उपयोगी है यदि आपके पास कई बार, कमांड-लाइन तर्कों के जटिल सेट हैं जिन्हें आप कई बार चलाने के लिए चाहते हैं।

पावरहेल कमांडलेट्स।

कमांडलेट पर निर्दिष्ट विशेषताओं, सत्यापन के लिए समर्थन, पैरामीटर सेट, पाइपलाइनिंग, त्रुटि रिपोर्टिंग, सहायता, और सभी कमांडिंग .NET ऑब्जेक्ट्स को अन्य कमांडलेट्स में उपयोग के लिए सबसे अच्छा पावरहेल द्वारा किया गया पार्सिंग।

एक जोड़े लिंक मुझे मदद मिल रही मददगार:


मैं ओपन-सोर्स लाइब्रेरी CSharpOptParse सुझाव CSharpOptParse । यह कमांड लाइन को पार्स करता है और कमांड लाइन इनपुट के साथ उपयोगकर्ता द्वारा परिभाषित .NET ऑब्जेक्ट को हाइड्रेट करता है। सी # कंसोल एप्लिकेशन लिखते समय मैं हमेशा इस लाइब्रेरी में बदल जाता हूं।


मैं दृढ़ता से NDesk.Options ( Documentation ) और / या Mono.Options (एक ही एपीआई, अलग नामस्थान) का उपयोग करने का सुझाव NDesk.Optionsदस्तावेज़ीकरण से एक उदाहरण :

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://www.codeplex.com/CommandLineArguments


कमांड लाइन पार्सिंग के लिए विज्ञापन हॉक क्लास का उपयोग करना बहुत आसान है, जो डिफ़ॉल्ट तर्कों का समर्थन करता है।

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




command-line-arguments