C # में कमांड लाइन तर्क को पार्स करने का सबसे अच्छा तरीका? [बन्द है]


731

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

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

इसलिए मुझे इसमें रुचि है:

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

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



1
हाय, खेद है कि यह थोड़ा सा विषय है। हालाँकि मैं आवेदन करने के लिए तर्क देने के लिए "एप्लिकेशन सेटिंग्स" का उपयोग करता हूं। मुझे इसका उपयोग करना काफी आसान लगा और तर्क / फाइल पार्सिंग लिखने की आवश्यकता नहीं है, और अतिरिक्त पुस्तकालय की कोई आवश्यकता नहीं है। msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
मुझे

44
@ मुझे कॉल करें स्टीव: कमांड लाइन के तर्कों का मतलब यह है कि वे प्रति कॉल अलग-अलग हो सकते हैं - आप एप्लिकेशन सेटिंग्स के साथ ऐसा कैसे करते हैं?
रीइनियरियरपोस्ट

जवाबों:


324

मैं दृढ़ता से 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;
}

14
NDesk.options बहुत अच्छा है, लेकिन यह वास्तव में एक से अधिक विशिष्ट कमांड के साथ कंसोल ऐप का समर्थन नहीं करता है। यदि आप ऐसा चाहते हैं, तो कई कॉनकोनसाइड का प्रयास करें जो NDesk.Options पर बनाता है: nuget.org/List/Packages/ManyConsole
Frank Schwieterman

5
जब मेरे पास कई अलग-अलग कमांड के साथ एक ऐप होता है, तो मैं OptionSets "लेयर" करता हूं। Mdoc ( docs.go-mono.com/index.aspx?link=man%3amdoc%281%29 ) लें , जिसमें "ग्लोबल" ऑप्शनसेट ( github.com/mono/mono/blob-master/mcs/tools/ है। mdoc /… ) जो प्रति-कमांड OptionSet (जैसे github.com/mono/mono/blob/master/mcs/tools/mdoc/… ) को
दर्शाता है

3
मेरे लिए एनडीएससी कोई काम नहीं है। पूर्णांक तर्क पढ़ सकते हैं, लेकिन तार नहीं। चर तर्क मानों के बजाय तर्क (जैसे 's', 'a' आदि) प्राप्त करते रहते हैं (जैसे 'serverName', 'ApplicationName')। इसके बदले 'कमांड लाइन पार्सर लाइब्रेरी' का इस्तेमाल किया। ठीक है तो अब तक।
Jay

2
@AshleyHenderson एक बात के लिए, यह छोटा और लचीला है। अधिकांश समाधान केवल वैकल्पिक नामित तर्कों के साथ काम करते हैं (जैसे, ऐसा नहीं कर सकते हैं git checkout master), या उनके तर्क लचीले नहीं हैं (यानी, --foo 123= --foo=123= -f 123= -f=123और भी -v -h= का समर्थन नहीं करता है -vh)।
वर्नट

1
@FrankSchwieterman जो इसका अपना उत्तर होना चाहिए। और टिप के लिए धन्यवाद, ManyConsole एक वास्तविक इलाज है, मेरे लिए पूरी तरह से फिट बैठता है।
क्वेंटिन-स्टारिन

197

मुझे वास्तव में कमांड लाइन पार्सर लाइब्रेरी ( 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();
    }
}

6
यह वह लाइब्रेरी है जिसे मैंने भी बसाया था। मैं एक बड़ी कंपनी के लिए आवेदन लिख रहा हूं जिसे कई वर्षों तक बनाए रखने की आवश्यकता है - यह पुस्तकालय 2005 से लगातार अपडेट किया गया है, लोकप्रिय लगता है, सी # समुदाय में सक्रिय लोगों द्वारा लिखा गया है, और मामले में बीएसडी शैली में लाइसेंस प्राप्त है समर्थन गायब हो जाता है।
चार्ल्स बर्न्स

मैं यह भी सलाह देता हूं। मेरी एकमात्र समस्या थी: अनुमति दी गई तर्क संयोजन निर्दिष्ट करना (उदाहरण के लिए अगर आर्ग्यूमेंट था तो स्रोत होना चाहिए और तर्क भी होना चाहिए) विशेषताओं के साथ करना संभव हो सकता है। लेकिन आप शायद इसे बेहतर तरीके से अलग कर सकते हैं तर्क सत्यापनकर्ता तर्क के साथ
Lyndon White

1
मुझे विकल्प वर्ग पसंद है। यह अनाम मापदंडों और झंडों का --recursiveभी समर्थन करता है।
वर्नाइट

2
मैंने अभी इसका परीक्षण किया है और मैंने कुछ ही मिनटों में अपने आवेदन के लिए विकल्प लागू किया है। पुस्तकालय का उपयोग करना बेहद सरल है।
Trismegistos

3
मैंने इस लाइब्रेरी को अपने लिए बहुत प्रतिबंधात्मक पाया। यदि आपको विशेष सेट की आवश्यकता है, तो आप प्रत्येक सेट के लिए आवश्यक विकल्पों को परिभाषित नहीं कर सकते हैं, इसलिए उन्हें मैन्युअल रूप से जांचना होगा। आप अनाम मानों के लिए न्यूनतम आवश्यकता को परिभाषित नहीं कर सकते, आपको उन्हें स्वयं भी जाँचना होगा। मदद स्क्रीन बिल्डर भी लचीला बिल्कुल नहीं। यदि लाइब्रेरी का व्यवहार आपकी आवश्यकताओं के अनुरूप नहीं है, तो आप इसे बदलने के लिए वस्तुतः कुछ भी नहीं कर सकते हैं।
सर्गेई कोस्त्रुकोव

50

WPF TestApi पुस्तकालय सी # विकास के लिए सबसे अच्छी कमांड लाइन पारसर्स में से एक के साथ आता है। मैं अत्यधिक एपीआई में Ivo Manolov के ब्लॉग से इसे देखने की सलाह देता हूं :

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

19
+1। कमांड-लाइन पार्सिंग कुछ ऐसा है जो वास्तव में एक तीसरे पक्ष के टूल के बजाय विक्रेता (यानी Microsoft) से आना चाहिए, भले ही विक्रेता का समर्थन गोल-गोल तरीके से हो।
जोएल कोएहॉर्न

2
उन्होंने कहा, स्वीकृत उत्तर (मोनो) अगली सबसे अच्छी बात है।
जोएल कोएहॉर्न

6
@ जोल, वह कौन सा हिस्सा है जो कमांड लाइन पार्सिंग को वेंडर से होना जरूरी है? आपके कारण क्या हैं?
ग्रीनोल्डमैन

3
@ उमरियस: मुझे लगता है कि उसका मतलब है कि यह शायद आउट ऑफ द बॉक्स होना चाहिए ... बहुत सारी चीजों की तरह :)
user7116

पुस्तकालय बहुत बड़ा है! मेरी ज़रूरत से ज़्यादा शामिल है ...
ररी

24

2
NDesk के विकल्पों में बहुत अच्छा API है
user35149

2
मैं NDFS के लिए एक और वोट जोड़ूंगा जो अच्छी तरह से काम करता है, गैर-घुसपैठिया और अच्छी तरह से प्रलेखित है।
टेरेंस

1
Mono.GetOptions बहुत पुराना है, NDesk.Options बहुत अच्छा है (या यदि आप चाहें तो Mono। )
मैट एनराइट

7
@ एडम ओरेन: मेरा जवाब 1 साल और 1 महीने का है! मोनो ट्रंक की संरचना को फिर से बनाया गया था। यह कोड अब anonsvn.mono-project.com/viewvc/branches/mono-2-2/mcs/class/… पर
abatishchev

6
@ टिप्पणी: यह Mono.GetOptions है, जो अप्रचलित है, मोनो नहीं। मोनो। अभी भी बनाए रखा है।
जौनप

14

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

http://bizark.codeplex.com/

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

से प्रलेखन ...

BizArk ढांचे में कमांड-लाइन पार्सिंग में ये प्रमुख विशेषताएं हैं:

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

2
मैंने पाया कि BizArk की कमांड-लाइन पार्सर दूसरों की तुलना में अधिक आसान और धाराप्रवाह है। अत्यधिक सिफारिशित!
बोरिस मोदिलेव्स्की


9

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


2
यह उपयोग करने के लिए बहुत सरल है और उनकी वेबसाइट चट्टानों। उनका सिंटैक्स हालांकि बहुत सहज नहीं है: myapp myverb -argname argvalue(होना चाहिए -argname) या myapp -help(आमतौर पर --help)।
दोपहर

@Wernight वर्ब पर IsDefault पैरामीटर का उपयोग कर सकते हैं कि इसे छोड़ा जा सकता है। मुझे स्थिति-संबंधी मापदंडों के लिए समर्थन नहीं मिला, लेकिन मैंने केवल स्थितीय मापदंडों का उपयोग किया जब मैं कमांड लाइन को स्वयं पार्स कर रहा था। आईएमएचओ द्वारा दिए गए मानों नामांकित तर्कों का उपयोग करना बहुत स्पष्ट है।
लाउडेनवियर

5

इस समस्या के कई समाधान हैं। पूर्णता के लिए और विकल्प प्रदान करने के लिए अगर कोई मेरी इच्छा है तो मैं अपने Google कोड लाइब्रेरी में दो उपयोगी कक्षाओं के लिए यह उत्तर जोड़ रहा हूं ।

पहला ArgumentList है जो केवल कमांड लाइन मापदंडों को पार्स करने के लिए जिम्मेदार है। यह स्विच '/ x: y' या '-x = y' द्वारा परिभाषित नाम-मूल्य जोड़े एकत्र करता है और 'अनाम' प्रविष्टियों की सूची भी एकत्र करता है। यहां मूल उपयोग पर चर्चा की गई है , यहां कक्षा देखें

इसका दूसरा भाग है CommandInterpreter जो आपके .Net वर्ग से पूरी तरह कार्यात्मक कमांड-लाइन अनुप्रयोग बनाता है। उदहारण के लिए:

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: "स्ट्रिंग मान"

यह उतना ही सरल या उतना ही जटिल है जितना आपको इसकी आवश्यकता है। आप कर सकते हैं स्रोत कोड की समीक्षा , मदद देखने , या बाइनरी डाउनलोड


4

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

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


4

आप मेरी एक गली पसंद कर सकते हैं

प्रयोग करने में आसान और विस्तार योग्य कमांड लाइन तर्क पार्सर। हैंडल: बूल, प्लस / माइनस, स्ट्रिंग, स्ट्रिंग सूची, सीएसवी, एन्यूमरेशन।

'/' में निर्मित हेल्प मोड।

'/ ??' में निर्मित और '/? डी' दस्तावेज़ जनरेटर मोड।

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

संपादित करें: यह मेरी परियोजना है और इस तरह के उत्तर को तीसरे पक्ष से समर्थन के रूप में नहीं देखा जाना चाहिए। मैंने कहा कि मैं इसका उपयोग प्रत्येक कमांड लाइन आधारित कार्यक्रम के लिए करता हूं जो मैं लिखता हूं, यह खुला स्रोत है और यह मेरी आशा है कि अन्य लोग इससे लाभान्वित हो सकते हैं।


बस एक FYI करें, कि आपको एक छोटा सा डिस्क्लेमर लगाना चाहिए कि आप Rug.Cmd प्रोजेक्ट से जुड़े हुए हैं (जैसा कि FAQ में बताया गया है): stackoverflow.com/faq#promotion - जब से आप किसी ओपन को प्रमोट कर रहे हैं, तो कोई बड़ी बात नहीं है। स्रोत परियोजना, लेकिन यह अभी भी एक अस्वीकरण जोड़ने के लिए अच्छा है;) वैसे ... +1 बहुत अच्छी तरह से किया जाता है।
जेसन डाउन

यह इंगित करने के लिए चीयर्स और +1 के लिए धन्यवाद, मैं यह सुनिश्चित करूंगा कि मैं अपनी संबद्धता के बारे में अधिक स्पष्ट हूं।
फिल तेव

कोई चिंता नहीं ... इस तरह की चीज के लिए कुछ स्टिकर्स हैं (मैं उनमें से एक नहीं हूं), इसलिए मुझे लोगों को सिर देना पसंद है। फिर, आमतौर पर ओपन सोर्स प्रोजेक्ट्स के लिए समस्या नहीं है। यह ज्यादातर लोगों को उनके (भुगतान) उत्पादों के लिए स्पैमिंग सिफारिशों से रोकने के लिए है।
जेसन डाउन

3

Http://www.codeplex.com/commonlibrarynet पर कमांड लाइन तर्क पार्सर है

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

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

- विन्यास : Qa - प्रारंभ : $ { आज } - क्षेत्र : 'न्यूयॉर्क' Settings01

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


2

यह एक हैंडलर है जिसे मैंने नॉवेल Optionsक्लास पर आधारित लिखा था ।

यह एक सांत्वना अनुप्रयोगों के लिए लक्षित है जो while (input !="exit")स्टाइल लूप को निष्पादित करता है, एक इंटरैक्टिव कंसोल जैसे कि एफ़टीपी कंसोल उदाहरण के लिए।

उदाहरण उपयोग:

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

2

मेरा व्यक्तिगत पसंदीदा है 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;
}

2

मैं हाल ही में FubuCore कमांड लाइन को लागू करने के लिए आया था जिसे मैं वास्तव में पसंद कर रहा हूं, इसके कारण:

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

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

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

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

2

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

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

कुछ लिंक जो मुझे मददगार लगे, शुरू हुए:


2

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


अच्छी तरह से प्रलेखित? प्रलेखन कहाँ है?
सुहास

आंतरिक प्रलेखन (कोडबेस में) के साथ-साथ बाहरी प्रलेखन ( फ़ोल्डर Readme.mkdमें फ़ाइल देखें Documentation) है।
बर्नार्ड

ठीक है, मैंने जल्दबाजी में टिप्पणी की। हो सकता है कि आप अपनी परियोजना को जीथब में स्थानांतरित कर सकते हैं और आपके दस्तावेज़ स्वचालित रूप से होम पेज पर दिखाई देने लगते हैं।
सुहास

1

चंगेज कमांड लाइन पार्सर थोड़ा पुराना हो सकता है, लेकिन यह बहुत ही संपूर्ण है और मेरे लिए बहुत अच्छा काम करता है।


उदास, लेकिन चंगेज कमांड लाइन पार्सर के पास कोई दस्तावेज नहीं है।
ओकेगन

यदि आप स्रोतों को देखते हैं तो नमूना है जो उपयोग के विकल्प दिखाता है। genghis.codeplex.com/SourceControl/changeset/view/9491#73699
devdimi

0

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



0

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

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"));
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.