在构建接受参数的控制台应用程序时,可以使用传递给Main的参数(string[] args)。
在过去,我只是简单地索引/循环该数组,并做了一些正则表达式来提取值。然而,当命令变得更加复杂时,解析就会变得非常糟糕。
我感兴趣的是:
你使用的库 你使用的模式
假设命令总是遵循常见的标准,比如这里回答的。
在构建接受参数的控制台应用程序时,可以使用传递给Main的参数(string[] args)。
在过去,我只是简单地索引/循环该数组,并做了一些正则表达式来提取值。然而,当命令变得更加复杂时,解析就会变得非常糟糕。
我感兴趣的是:
你使用的库 你使用的模式
假设命令总是遵循常见的标准,比如这里回答的。
当前回答
我强烈建议使用NDesk。选项(文档)和/或Mono。选项(相同的API,不同的名称空间)。文档中的一个例子:
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;
}
其他回答
我强烈建议使用NDesk。选项(文档)和/或Mono。选项(相同的API,不同的名称空间)。文档中的一个例子:
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;
}
我个人最喜欢的是Peter palota的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;
}
这个问题有很多解决方案。为了完整性和提供替代方案,如果有人需要,我在我的谷歌代码库中添加了两个有用的类的答案。
第一个是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)
{ ... }
使用上面的示例代码,您可以运行以下代码:
exe DoSomething“字符串值
——或——
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"));
}
}
我建议使用开源库CSharpOptParse。它解析命令行,并将用户定义的. net对象与命令行输入结合起来。在编写c#控制台应用程序时,我总是使用这个库。