在 C# 中解析命令行参数的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/491595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to parse command line arguments in C#?
提问by Paul Stovell
When building console applications that take parameters, you can use the arguments passed to Main(string[] args)
.
在构建带参数的控制台应用程序时,您可以使用传递给Main(string[] args)
.
In the past I've simply indexed/looped that array and done a few regular expressions to extract the values. However, when the commands get more complicated, the parsing can get pretty ugly.
在过去,我只是简单地索引/循环该数组并执行一些正则表达式来提取值。然而,当命令变得更复杂时,解析会变得非常难看。
So I'm interested in:
所以我感兴趣的是:
- Libraries that you use
- Patterns that you use
- 您使用的库
- 你使用的模式
Assume the commands always adhere to common standards such as answered here.
假设命令始终遵循通用标准,例如这里的回答。
采纳答案by jonp
I would strongly suggest using NDesk.Options(Documentation) and/or Mono.Options(same API, different namespace). An example from the documentation:
我强烈建议使用NDesk.Options(文档)和/或Mono.Options(相同的 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;
}
回答by abatishchev
回答by Xn0vv3r
I like that one, because you can "define rules" for the arguments, needed or not,...
我喜欢那个,因为您可以为参数“定义规则”,无论是否需要,...
or if you're a Unix guy, than you might like the GNU Getopt .NETport.
或者,如果您是 Unix 人,那么您可能会喜欢GNU Getopt .NET端口。
回答by user7116
The WPF TestApi librarycomes with one of the nicest command line parsers for C# development. I highly recommend looking into it, from Ivo Manolov's blog on the API:
在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);
回答by user7116
There is a command line argument parser at http://www.codeplex.com/commonlibrarynet
http://www.codeplex.com/commonlibrarynet 上有一个命令行参数解析器
It can parse arguments using
1. attributes
2. explicit calls
3. single line of multiple arguments OR string array
它可以使用
1. 属性
2. 显式调用
3. 单行多参数 OR 字符串数组来解析参数
It can handle things like the following:
它可以处理以下事情:
-config:Qa -startdate:${today} -region:'New York' Settings01
-配置:QA - STARTDATE:$ {今天} -区域: '纽约' Settings01
It's very easy to use.
它非常容易使用。
回答by Chris S
This is a handler I wrote based on the Novell Options
class.
这是我基于 NovellOptions
类编写的处理程序。
This one is aimed at console applications that execute a while (input !="exit")
style loop, an interactive console such as an FTP console for example.
这个是针对执行while (input !="exit")
样式循环的控制台应用程序,一个交互式控制台,例如 FTP 控制台。
Example usage:
用法示例:
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();
}
}
And the source:
和来源:
/// <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;
}
}
回答by devdimi
Genghis Command Line Parsermay be a little out of date, but it is very feature complete and works pretty well for me.
Genghis 命令行解析器可能有点过时,但它的功能非常完整,对我来说效果很好。
回答by PeterH
I wrote a C# command line argument parser a while back. Its at: http://www.codeplex.com/CommandLineArguments
不久前我写了一个 C# 命令行参数解析器。它位于:http: //www.codeplex.com/CommandLineArguments
回答by csharptest.net
There are numerous solutions to this problem. For completeness and to provide the alternative if someone desires I'm adding this answer for two useful classes in my google code library.
这个问题有很多解决方案。为了完整性并在有人需要时提供替代方案,我在我的google 代码库中为两个有用的类添加了这个答案。
The first is ArgumentList which is responsible only for parsing command line parameters. It collects name-value pairs defined by switches '/x:y' or '-x=y' and also collects a list of 'unnamed' entries. It's basic usage is discussed here, view the class here.
第一个是 ArgumentList,它只负责解析命令行参数。它收集由开关“/x:y”或“-x=y”定义的名称-值对,并收集“未命名”条目列表。它的基本用法是这里讨论,在这里查看类。
The second part of this is the CommandInterpreterwhich creates a fully-functional command-line application out of your .Net class. As an example:
第二部分是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)
{ ... }
With the above example code you can run the following:
使用上面的示例代码,您可以运行以下命令:
Program.exe DoSomething "string value" 5
Program.exe DoSomething “字符串值” 5
-- or --
- 或者 -
Program.exe dosomething /ivalue=5 -svalue:"string value"
Program.exe dosomething /ivalue=5 -svalue:"字符串值"
It's as simple as that or as complex as you need it to be. You can review the source code, view the help, or download the binary.
回答by Brian
Looks like everybody has their own pet command-line parsers, figure I had better add mine as well :).
看起来每个人都有自己的宠物命令行解析器,我最好也添加我的:)。
This library contains a command-line parserthat will initialize a class with the values from the command-line. It has a ton of features (I've been building it up over many years).
这个库包含一个命令行解析器,它将用来自命令行的值初始化一个类。它有很多功能(我多年来一直在构建它)。
From the documentation...
从文档...
Command-line parsing in the BizArk framework has these key features:
BizArk 框架中的命令行解析具有以下关键特性:
- Automatic initialization:Class properties are automatically set based on the command-line arguments.
- Default properties:Send in a value without specifying the property name.
- Value conversion:Uses the powerful ConvertEx class also included in BizArk to convert values to the proper type.
- Boolean flags:Flags can be specified by simply using the argument (ex, /b for true and /b- for false) or by adding the value true/false, yes/no, etc.
- Argument arrays:Simply add multiple values after the command-line name to set a property that is defined as an array. Ex, /x 1 2 3 will populate x with the array { 1, 2, 3 } (assuming x is defined as an array of integers).
- Command-line aliases:A property can support multiple command-line aliases for it. For example, Help uses the alias ?.
- Partial name recognition:You don't need to spell out the full name or alias, just spell enough for the parser to disambiguate the property/alias from the others.
- Supports ClickOnce:Can initialize properties even when they are specified as the query string in a URL for ClickOnce deployed applications. The command-line initialization method will detect if it is running as ClickOnce or not so your code doesn't need to change when using it.
- Automatically creates /? help:This includes nice formatting that takes into account the width of the console.
- Load/Save command-line arguments to a file:This is especially useful if you have multiple large, complex sets of command-line arguments that you want to run multiple times.
- 自动初始化:根据命令行参数自动设置类属性。
- 默认属性:在不指定属性名称的情况下发送值。
- 值转换:使用强大的 ConvertEx 类也包含在 BizArk 中,将值转换为正确的类型。
- 布尔标志:标志可以通过简单地使用参数(例如,/b 表示真和 /b- 表示假)或通过添加值 true/false、yes/no 等来指定。
- 参数数组:只需在命令行名称后添加多个值即可设置定义为数组的属性。例如, /x 1 2 3 将用数组 { 1, 2, 3 } 填充 x (假设 x 被定义为一个整数数组)。
- 命令行别名:一个属性可以支持多个命令行别名。例如,帮助使用别名 ?。
- 部分名称识别:您不需要拼出全名或别名,只需拼写足以让解析器消除其他属性/别名的歧义即可。
- 支持 ClickOnce:即使属性被指定为 ClickOnce 部署应用程序的 URL 中的查询字符串,也可以初始化这些属性。命令行初始化方法将检测它是否作为 ClickOnce 运行,因此您的代码在使用时不需要更改。
- 自动创建 /? 帮助:这包括考虑到控制台宽度的漂亮格式。
- 将命令行参数加载/保存到文件:如果您有多个大型、复杂的命令行参数集想要多次运行,这将特别有用。