在构建接受参数的控制台应用程序时,可以使用传递给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;
}
其他回答
这是我基于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;
}
}
我个人最喜欢的是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;
}
看看http://github.com/mono/mono/tree/master/mcs/class/Mono.Options/
请使用apache commons cli API的。net端口。这很有效。
http://sourceforge.net/projects/dotnetcli/
以及用于概念和介绍的原始API
http://commons.apache.org/cli/
WPF TestApi库提供了c#开发中最好的命令行解析器之一。我强烈推荐你去看看,这是Ivo Manolov关于API的博客:
// 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);