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




.net command-line-arguments (14)

आप मेरे एक Rug.Cmd पसंद कर सकते हैं

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

'/?' में निर्मित सहायता मोड

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

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

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

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

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

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

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

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


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

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

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


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

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


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


मैं ओपन-सोर्स लाइब्रेरी 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


यह एक हैंडलर है जिसे मैंने नोवेल 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;
    }
}


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


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

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

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

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

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






command-line-arguments