我创建了一个控制台应用程序,该应用程序具有一个菜单,允许我在菜单项之间导航。我通过这种方法处理导航逻辑:
public virtual void updateMenu()
{
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.UpArrow:
{
if (cursor > 0)
{
cursor--;
Console.Clear();
drawWithHeader();
}
}
break;
case ConsoleKey.DownArrow:
{
if (cursor < (menuItemList.Count - 1))
{
cursor++;
Console.Clear();
drawWithHeader();
}
}
break;
case ConsoleKey.Escape:
{
if (ParentMenu != null)
{
hideMenu();
}
}
break;
case ConsoleKey.Enter:
{
Console.Clear();
drawHeader();
Console.CursorVisible = true;
menuItemList[cursor].Action();
Console.CursorVisible = false;
Console.Clear();
drawWithHeader();
}
break;
default:
{
// Unsuported key. Do nothing....
}
break;
}
}
现在在Windows上一切正常,但是当我使用systemd
在Linux上运行此应用程序时,我得到:
未处理的异常:System.InvalidOperationException:当任一应用程序没有控制台或控制台输入已重定向时,无法读取键。尝试Console.Read。
stacktrace显示:
at System.ConsolePal.ReadKey(Boolean intercept)
at System.Console.ReadKey();
at AppRazen.Menu.ConsoleMenu.UpdateMenu();
经过一番搜索,我发现此问题与ReadKey()
方法有关,并非完全compatible with linux。提议的解决方案here在我的情况下根本行不通,因为用户使用了OminSharp
。
我也尝试设置ReadKey(false)
,但这并不能解决问题,我还尝试使用UpdateMenu
处理Console.Read()
中的所有内容,但控制台似乎卡住了。 / p>
请注意,仅当我在linux主管中运行脚本而不使用dotnet AppRazen.dll
这样的默认命令时,才会发生此问题
基本上,我正在使用systemd
服务来运行脚本,如下所示:
[Unit]
Description = Daemon description
[Service]
ExecStart = /usr/bin/dotnet /home/root/Desktop/publish/AppRazen.dll
WorkingDirectory= /home/root/Desktop/publish
Restart = always
RestartSec = 3
[Install]
WantedBy = multi-user.target
老实说,我不知道该如何解决。有人有什么想法吗?
谢谢。
答案 0 :(得分:1)
做自己想做的事的简短答案是,你根本做不到。
考虑一下:您正在尝试创建一个交互式程序(用户可以通过键盘与之交互)。但是,您也将其设置为守护程序(守护进程会在后台运行,并且不会直接与用户进行交互)。这是两个相互矛盾的目标。
当systemd
(或supervisord
或upstart
或实际上任何系统服务程序)将应用程序作为服务运行时,它并没有提供与用户交互的方式,因为这些应用程序希望成为守护程序-这意味着用户无法与它们进行交互。
因此,问自己想做什么:是否要制作一个交互式程序?如果要制作交互式程序,则不能通过主管运行它。通过dotnet /path/to/your.dll
直接运行它。
其他评论:
ReadKey
可能有问题,但是在您要干的普通情况下(当然似乎不是x86_64上的Linux),肯定没有问题。
OmniSharp是IDE /文本编辑器的插件,可简化开发。它提供自动完成和实时语法突出显示功能。在运行应用程序时不涉及此操作。