实现C#控制台应用程序的正确方法是什么?

22

如何正确实现和构建一个 C# 控制台应用作为命令行工具?

需要解决的问题包括正确解析命令行变量以及正确输出文本。尽管 Console.WriteLine() 是最明显的输出选择,但在哪种情况下应该选择写入标准错误流、.Error、.SetErrorStream 等呢?

应用程序如何在返回适当的返回代码给调用命令的同时正确退出?

如何实现 CancelKeyPress 事件以中断程序?它只用于异步操作在单独的线程上进行时吗?

是否有关于 C# 命令行工具编程的简明指南,甚至更好的是一个开源项目或模板,我可以用来正确地实现一个相对简单的工具呢?


重复?请看这里:https://dev59.com/sXRA5IYBdhLWcg3wzhXZ - Dervin Thunk
请参阅:http://stackoverflow.com/questions/664533/best-command-line-option-parsers-for-c-c-and-c-closed - Dervin Thunk
1
我的问题是对.NET控制台应用程序机制的更广泛探索,包括正确使用ErrorStream和CancelKeyPress事件的方法。这两篇文章分别与命令行解析和类结构有关。 - James
5个回答

27

错误消息应该写入stderr,也就是Console.Error,而正常输出应该写入stdout,也就是Console.Out。对于“过滤器”类型的控制台应用程序来说,这一点尤为重要,因为它们的输出(stdout)可以被传输到另一个进程中,例如在批处理文件中。

通常情况下,如果遇到错误,应该将错误消息写入Console.Error并返回非零结果。或者如果是异常,就不必处理它。

要返回结果代码,可以将其作为参数传递给Environment.Exit,设置Environment.ExitCode属性,或从main函数返回非零值。

对于简单的控制台应用程序,我会:

  • 编写一个帮助类来解析命令行。

  • 编写一个门面类,为您的命令行工具实现的功能提供可测试的API。与大多数.NET API一样,如果发生错误,通常会抛出异常。

  • 主程序只需使用帮助程序解析命令行,并调用API传递从命令行传递的参数。它可以选择捕获API抛出的异常,记录它们,向Console.Error写入面向用户的错误消息,并设置非零返回代码。

但我不认为这是唯一正确的方法:实际上并没有这样的方法,这就是为什么你很难找到你要找的书的原因。


5

关于如何实现命令解析,我以前用过反射和委托成功地实现。工作原理是使用特殊的属性对命令方法进行修饰,该属性由您自己创建,指定该方法应该可通过方法名称或属性中指定的字符串被用户调用,例如:

[Command("quit")]
public void QuitApp()
{
    ...
}

在程序启动时,您可以扫描一个类以查找这些方法,并将针对它们的委托存储在一个字典中,其中键是命令。这使得根据字典中的第一个单词解析命令变得容易(平摊O(1)),并且随着添加新命令,易于扩展和维护,只需添加单独的方法即可。

2

关于命令行参数,你会发现有各种不同的方案,但我一直是其粉丝之一。

app.exe "self-explanatory arg" /noArgumentSwitch /argumentSwitch="argument"

关于返回代码,您可以更改Main()函数的签名,使其返回一个int而不是void。这将允许您在必要时将代码返回给调用进程。
至于错误流,我个人从未使用过它,并且我认为它不应该以输出标准输出流中的错误信息为代价。它可能更适合用于特定的错误调试信息。

2

对于命令行处理,可以使用Mono.GetOptions。它可以轻松地从短选项(-f样式)和长选项(--file样式)的命令行选项中填充变量。


0
我选择将一些控制台实用程序编写为窗体应用程序而不是控制台应用程序。通常,我会添加一个计时器来延迟初始启动,并添加一个带有进度条的取消按钮,从而提供更直观的取消选项。这样你仍然可以通过控制台输出信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接