.net 在控制台应用程序中使用连字符命名的输入(例如-S“myServerName”)的简单方法是什么?

v6ylcynt  于 2022-12-20  发布在  .NET
关注(0)|答案(4)|浏览(105)

我希望我的控制台应用使用连字符命名的输入,如下所示:

myApp -S "myServerName" -D "myDatabaseName"

而不是通常的

myApp "myServerName" "myDatabaseName"

我认为第一种方式对那些想使用我的控制台应用程序的开发者来说更友好,我想我不知道这种输入方式叫什么,否则我会在谷歌上找到它。

0x6upsns

0x6upsns1#

在可执行文件名之后输入的所有内容都称为命令行参数。
但是,是否使用破折号、斜线或其他类型的关键字完全取决于应用程序的实现。
如果您想保存一些精力,您可能希望使用命令行解析器。
下面是一个开源的示例,您可以使用它。http://www.codeplex.com/cmdline

atmip9wb

atmip9wb2#

我喜欢使用NDesk.Options。你只需要把源文件添加到你的项目中。它真的很容易使用,并且有很好的文档。代码看起来像:

string server = null;
string database = null;
var p = new OptionSet () {
    { "S",  v => server = v },
    { "D",  v => database = v },
   };
List<string> extra = p.Parse (args); // 'args' comes from Main (string [] args)
...

如果要生成自动帮助,您可以执行以下操作:

string server = null;
string database = null;
var p = new OptionSet () {
    { "S", "Server name", v => server = v },
    { "D", "Database name", v => database = v },
    { "h", "Display help", v => { show_help = true; }},
   };
List<string> extra = p.Parse (args); // 'args' comes from Main (string [] args)
if (show_help) {
   Console.WriteLine ("Name of your program and brief description");
   p.WriteOptionDescriptions (Console.Out);
   Environment.Exit (0);
}
...
ltskdhd1

ltskdhd13#

把它放在arg-processing方法中:

for (int i=0; i < args.Length; i++)
    {
        switch (args[i])
        {
            case "-f":  // string data
                i++;
                if (args.Length <= i) throw new ArgumentException(args[i]);
                _file = args[i];
                break;

            case "-p":  // boolean flag
                _pflag= true;
                break;

            case "-i":  // int argument, allows hex or decimal
                i++;
                if (args.Length <= i) throw new ArgumentException(args[i]);
                if (_intParam != DefaultIntParamValue)
                    throw new ArgumentException(args[i]);
                if (args[i].StartsWith("0x"))
                    _intParam = System.Int32.Parse(args[i].Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier );
                else
                    _intParam = System.Int32.Parse(args[i]);
                break;

            case "-s":  // size, in bytes, K, MB, GB
                i++;
                if (args.Length <= i) throw new Exception(args[i-1]);
                if (args[i].ToUpper().EndsWith("K"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-1)) * 1024;
                else if (args[i].ToUpper().EndsWith("KB"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-2)) * 1024;
                else if (args[i].ToUpper().EndsWith("M"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-1)) * 1024*1024;
                else if (args[i].ToUpper().EndsWith("MB"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-2)) * 1024*1024;
                else
                    _size = Int32.Parse(args[i]);
                break;

            case "-?":
                throw new ArgumentException(args[i]);

            default:  // positional argument
                if (_positionalArg != null)
                    throw new ArgumentException(args[i]);

                _positionalArg = args[i];
                break;
        }
    }

我经常把它放到“runner”类型的构造函数中。
这个逻辑假设arg处理是在try.. catch中完成的,并且在catch中显示Usage,如下所示:

try 
{
    MyClass x = new MyClass(args);
    x.DoTheThing(); 
}
catch (Exception exc1)
{
   Usage(); 
}
igsr9ssn

igsr9ssn4#

您可以编写一个将string[]转换为Dictionary<string, string>的方法:

public static class NamedArgs
{
    public static IDictionary<string, string> ToDictionary(string[] args)
    {
        var dict = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

        for (int i = 0; i < args.Length; i++)
            if (args[i].StartsWith("-"))
            {
                if (i + 1 >= args.Length || args[i + 1].StartsWith("-"))
                    dict.Add(args[i], string.Empty);
                else
                    dict.Add(args[i], args[++i]);
            }

        return dict;
    }
}

它的用法如下:

var namedArgs = NamedArgs.ToDictionary(args);
        
if(namedArgs.TryGetValue("-s", out string myServerName) == false)
    throw new ArgumentNullException("-s");

Console.WriteLine($"Selected server: '{myServerName}'");

相关问题