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

时间:2009-05-07 19:14:16

标签: c# command-line console arguments

将命令行工具实现和构建为C#控制台应用程序的正确方法是什么?

对地址的关注包括正确解析命令行变量以及输出文本的正确方法。虽然Console.WriteLine()是输出最明显的选择,但在什么情况下应该选择写入标准错误流,.Error,.SetErrorStream等?

在将正确的返回代码返回给调用命令时,应用程序退出的正确方法是什么?

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

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

5 个答案:

答案 0 :(得分:25)

错误消息应写入stderr aka Console.Error,并正常输出到stdout aka Console.Out。这对于“过滤器”类型的控制台应用程序尤其重要,其输出(stdout)可以通过管道输送到另一个进程,例如在批处理文件中。

通常,如果遇到错误,请向Console.Error写入错误消息并返回非零结果。或者,如果它是一个例外,就不要费心去处理它。

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

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

  • 有一个帮助程序类来解析命令行。

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

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

但我不认为这是一种真实的方式:实际上并没有这样的事情,这就是为什么你不太可能找到你正在寻找的书。

答案 1 :(得分:5)

至于如何实现命令解析,我以前成功地使用了反射和委托。它们的工作方式是使用您自己创建的特殊属性来装饰命令方法,该属性表明该方法应该是用户可调用的,可以通过方法的名称或属性中指定的字符串,即:

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

在程序启动时,您可以扫描类以获取此类方法,并将指向它们的委托存储在字典中,其中键是命令。这使得在查找字典中的第一个单词(分摊的O(1))并且可以轻松扩展和管理以便将来解析命令变得容易,因为添加新命令只需添加单独的方法。

答案 2 :(得分:2)

至于命令行参数,你会发现各种方案,但我一直是

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

对于返回代码,您可以更改Main()函数的签名,以返回int而不是void。这将允许您在必要时将代码返回给调用进程。

至于错误流,我从未亲自使用它,我认为它不应以牺牲在标准输出流中输出错误信息为代价。它可能更适合用于特定的错误调试信息。

答案 3 :(得分:2)

对于命令行处理,请查看Mono.GetOptions。它可以很容易地从短(-f style)和long( - file style)命令行选项填充变量。

答案 4 :(得分:0)

我选择将一些控制台实用程序应用程序编写为Windows窗体应用程序而不是控制台应用程序。通常,我添加一个计时器来延迟初始启动,只需添加带有进度表的取消按钮 - 从而允许更直观的取消选项。您仍然可以通过这种方式输出到控制台。