终端
Zongsoft.Terminals 终端抽象、控制台终端和交互式命令模式。
Zongsoft.Terminals 把控制台程序抽象为终端和终端命令执行器。终端负责输入、输出、样式和中断事件;执行器继承命令执行模型,负责读取命令、执行命令和维护当前命令节点。
Terminal.Console 是核心库提供的默认控制台终端,内部封装 System.Console。Terminal.Default 默认指向控制台终端,也可以被宿主或测试代码替换成其它实现。
关键类型
ITerminal
终端接口,继承 ICommandOutlet,提供输入、输出、错误输出、样式、清屏和重置。
ITerminalExecutor
终端命令执行器接口,继承 ICommandExecutor,提供 Run/RunAsync 和退出事件。
Terminal
静态入口,提供 Default、Console、输出和样式快捷方法。
ConsoleTerminal
控制台终端实现,封装 System.Console、ANSI 样式和 Ctrl+C 中断。
ConsoleExecutor
控制台命令执行器,读取终端输入并执行命令。
TerminalStyles
终端样式重置选项。
Terminal.ExitException
终端命令用于退出命令循环的专用异常。
启动终端
终端执行器运行时会打印闪屏、进入命令循环并等待用户输入。可以传入纯文本闪屏,也可以传入 CommandOutletContent 组合多色输出。
来源:framework/Zongsoft.Net/samples/server/Program.cs(节选;上下文见源文件)。
var splash = CommandOutletContent.Create()
.AppendLine(CommandOutletColor.Yellow, new string('·', 50))
.AppendLine(CommandOutletColor.Blue, "Welcome to the TCP Server.".Justify(50))
.AppendLine(CommandOutletColor.Yellow, new string('·', 50));
await executor.RunAsync(splash);上面是 framework TCP 服务端样例的启动片段,executor 及 start、stop、info 命令在同一 Program.cs 前部创建;完整入口见常规通讯。Discussions 自己的站内信命令复用宿主执行器,不重复创建终端。
命令循环会把输出编码设置为 UTF-8。每次读取命令前会重置终端样式,并显示提示符:根节点下显示 $>,进入某个命令节点后显示该节点完整路径。
命令循环
交互式响应模式
Terminal.ReactiveAsync(...) 让命令进入“运行中等待中断”的模式。它会检查当前执行器是否是终端执行器,挂载终端的 Aborting 事件,然后等待 Ctrl+C 释放信号量,最后执行退出回调。
来源:framework/Zongsoft.Commands/src/Messaging/QueueSubscribeCommand.cs(节选;上下文见源文件)。
Zongsoft.Commands 中的消息队列订阅命令就是这种结构:进入时订阅队列并持续输出消息,用户按 Ctrl+C 后退出并注销订阅。
输出样式
ITerminal 继承 ICommandOutlet,因此命令可以使用 CommandOutletContent 组合颜色、样式和文本片段。控制台终端会把这些样式转换为 ANSI 转义序列输出。
来源:framework/Zongsoft.Core/samples/memorycache/Program.cs(节选;上下文见源文件)。
这段输出来自 核心类库 的 memorycache 交互样例,Now 是同一类的时间文本属性,e 来自缓存淘汰事件。命令内部通常优先使用 context.Output,这样同一命令既可以在终端中输出,也可以被其它命令执行器复用。只有确定输出目标就是当前默认终端时,才直接使用 Terminal.WriteLine(...)。
终端扩展方法
Terminal.Utility 提供了从命令执行器或命令上下文取得终端的扩展方法:
GetTerminal(this ICommandExecutor executor)
如果执行器是终端执行器,返回所属终端。
GetTerminal(this CommandContextBase context)
从命令上下文取得所属终端。
TryGetTerminal(...)
尝试取得终端,适合命令兼容终端和非终端两种环境。
ReactiveAsync(...)
让命令进入 Ctrl+C 退出的响应式模式。
使用建议
终端程序适合本地调试、插件管理、样例程序和运维工具。面向多用户或远程管理的场景,仍需要额外考虑权限、审计、命令白名单和外部命令限制。
如果命令需要长期运行并等待用户中断,优先使用 ReactiveAsync(...) 包住进入和退出逻辑;如果命令只执行一次动作,直接实现普通 CommandBase<CommandContext> 即可。
参考实现
最后更新于