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

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

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

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

如何实现CancelKeyPress事件来中断程序? 它是否仅在单独线程上发生异步操作时使用?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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