在C#中解析命令行参数的最佳方法?

在C#中解析命令行参数的最佳方法?,c#,.net,command-line-arguments,C#,.net,Command Line Arguments,构建带有参数的控制台应用程序时,可以使用传递给Main(string[]args)的参数 在过去,我只是对该数组进行索引/循环,并使用一些正则表达式来提取值。但是,当命令变得更复杂时,解析可能会变得非常难看 因此,我感兴趣的是: 您使用的库 您使用的模式 假设命令始终遵循公共标准,例如。看看我喜欢的,因为您可以为参数“定义规则”,无论是否需要 或者,如果您是Unix用户,您可能会喜欢这个端口。该端口附带了一个用于C#开发的最好的命令行解析器。我强烈建议从以下方面进行调查: 下面是一个命令行参

构建带有参数的控制台应用程序时,可以使用传递给
Main(string[]args)
的参数

在过去,我只是对该数组进行索引/循环,并使用一些正则表达式来提取值。但是,当命令变得更复杂时,解析可能会变得非常难看

因此,我感兴趣的是:

  • 您使用的库
  • 您使用的模式
假设命令始终遵循公共标准,例如。

看看我喜欢的,因为您可以为参数“定义规则”,无论是否需要

或者,如果您是Unix用户,您可能会喜欢这个端口。

该端口附带了一个用于C#开发的最好的命令行解析器。我强烈建议从以下方面进行调查:


下面是一个命令行参数解析器

它可以使用
1.属性
2.显式调用
3.单行多参数或字符串数组

它可以处理以下情况:

-配置:Qa-开始日期:${today}-地区:“纽约”设置01


它非常容易使用。

这是我基于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;
    }
}
//
///用于分析工具内命令的类。基于Novell选项类(http://www.ndesk.org/Options).
/// 
公共类命令选项
{
私人字典(行动),;
私有字典_actionsNoParams;
/// 
///初始化类的新实例。
/// 
公共命令选项()
{
_actions=newdictionary();
_actionsNoParams=新字典();
}
/// 
///添加找到命令时要执行的命令选项和操作。
/// 
///命令的名称。
///行动代表
///当前CommandOptions实例。
公共命令选项添加(字符串名称、操作)
{
_actionsNoParams.Add(名称、操作);
归还这个;
}
/// 
///添加找到命令时要执行的命令选项和操作(带参数)。
/// 
///命令的名称。
///具有一个参数的操作委托-字符串[]args。
///当前CommandOptions实例。
公共命令选项添加(字符串名称、操作)
{
_操作。添加(名称、操作);
归还这个;
}
/// 
///解析文本命令并调用与该命令关联的任何操作。
/// 
///文本命令,例如“显示数据库”
公共布尔解析(字符串命令)
{
if(command.IndexOf(“”==-1)
{
//无参数
foreach(字符串键输入_actionsNoParams.Keys)
{
如果(命令==键)
{
_actionsNoParams[key].Invoke();
返回true;
}
}
}
其他的
{
//Params
foreach(字符串键入_actions.Keys)
{
if(command.StartsWith(key)&&command.Length>key.Length)
{
字符串选项=command.Substring(key.Length);
options=options.Trim();
string[]parts=options.Split(“”);
_操作[键]。调用(部件);
返回true;
}
}
}
返回false;
}
}

可能有点过时,但它的功能非常完整,对我来说效果非常好。

我不久前编写了一个C#命令行参数解析器。它位于:

我强烈建议使用()和/或(相同的API,不同的名称空间)。安:

bool show\u help=false;
列表名称=新列表();
int repeat=1;
var p=新的OptionSet(){
{“n | name=”,“要问候的人的{name}。”,
v=>names.Add(v)},
{“r | repeat=”,
重复问候的次数{次}。\n“+
“这必须是一个整数。”,
(int v)=>repeat=v},
{“v”,“增加调试消息的详细程度”,
v=>{if(v!=null)++verbosity;}},
{“h |帮助”,“显示此消息并退出”,
v=>show_help=v!=null},
};
额外列出;
试一试{
额外=p.解析(args);
}
捕获(OptionException e){
控制台。写(“问候:”);
Console.WriteLine(e.Message);
Console.WriteLine(“有关更多信息,请尝试使用‘问候——帮助’”);
返回;
}

这个问题有很多解决方案。为了完整性,如果有人愿意,我将为我的系统中的两个有用的类添加这个答案

第一个是ArgumentList,它只负责解析命令行参数。它收集由开关“/x:y”或“-x=y”定义的名称-值对,还收集“未命名”项的列表。这是基本的

第二部分是,它从.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-s值:“字符串值”


就这么简单,或者你需要的那么复杂。您可以,或者。

看起来每个人都有自己的pet命令行解析器,我最好也添加我的:)

此库包含将使用命令行中的值初始化类的。它有很多特性(我已经建立了很多年了)

BizArk框架中的命令行解析具有以下关键功能:

  • 自动初始化:类属性不可用
    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;
    }
    
    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)
            { ... }
    
    [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;
    }
    
    [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;
        }
    }
    
    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
      -------------------------------------
    
    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"));
        }
    }
    
    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();
        }
    }
    
    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);
            }
        }
    }