如何在 dotnet 应用程序中创建导航菜单? [英] How to create a navigation menu in dotnet application?

查看:22
本文介绍了如何在 dotnet 应用程序中创建导航菜单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个控制台应用程序,它有一个菜单,允许我在菜单项之间导航.我在这个方法中处理导航逻辑:

I have created a console application which have a menu that allow me to navigate between the menu items. I handle the navigation logic in this method:

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 上运行这个应用程序时,我得到:

Now on windows all works well, but when I run this application on my linux with systemd I get:

未处理的异常:System.InvalidOperationException:当任一应用程序没有控制台或控制台输入已被重定向时,无法读取密钥.试试 Console.Read.

Unhandled Exception: System.InvalidOperationException: Cannot read key when either application does not have a console or when console input has been redirected. Try Console.Read.

堆栈跟踪显示:

at System.ConsolePal.ReadKey(Boolean intercept)
at System.Console.ReadKey();
at AppRazen.Menu.ConsoleMenu.UpdateMenu();  

经过一番搜索,我发现这个问题与 ReadKey() 方法不完全有关 与 linux 兼容.而此处提出的解决方案在我的情况下根本不起作用,因为用户已使用 OminSharp.

After some searching I discovered that this problem is related to the ReadKey() method is not fully compatible with linux. And the solution proposed here simply doesn't work in my case, because the user has used OminSharp.

我也尝试设置 ReadKey(false) 但这并没有解决问题,我还尝试使用 处理 UpdateMenu 中的所有内容Console.Read() 但控制台似乎卡住了.

I also tried to set ReadKey(false) but this didn't fixed the problem, and I also tried to handle all the stuff inside UpdateMenu with Console.Read() but the console seems stuck.

请注意,只有当我在 linux supervisor 中运行我的脚本而不使用像 dotnet AppRazen.dll

Note that this issue will happen only when I run my script in linux supervisor not with the default command like dotnet AppRazen.dll

本质上,我正在使用这样的 systemd 服务运行脚本:

Essentially I'm running the script with a systemd service like this:

[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

老实说,我不知道如何解决这个问题.有人有什么想法吗?

I honestly I don't know how can I fix that. Someone have any ideas?

提前致谢.

推荐答案

做你想做的事的简短回答是你根本做不到.

The short answer to doing what you want to do is that you simply can't.

想一想:您正在尝试开发一个交互式程序(用户可以通过键盘与之交互).但是你也让它成为一个守护进程(守护进程运行后台并且不直接与用户交互).这是两个相互矛盾的目标.

Think about it: you are trying to have an interactive program (that users can interact with via the keyboard). But you are also making it a daemon (a deamon runs the background and doesn't interact with users directly). These are two contradictory goals.

systemd(或 supervisord,或 upstart 或任何系统服务程序)将您的应用程序作为服务运行时,它不会给它一种与用户交互的方式,因为这些应用程序想要成为守护进程——这意味着用户无法与他们交互.

When systemd (or supervisord, or upstart or really any system services program) runs your application as a service, it doesn't give it a way to interact with users, since these applications want to be daemons - which means users can't interact with them.

那么,问问自己你想做什么:你想制作一个交互式程序吗?如果你想制作一个交互式程序,你不能通过主管运行它.通过 dotnet/path/to/your.dll 直接运行它.

So, ask yourself what you want to do: do you want to make an interactive program or not? If you want make an interactive program you can't run it via supervisor. Run it directly, via dotnet /path/to/your.dll.

其他评论:

  • ReadKey 可能有问题,但肯定不会出现在您正在努力做的常见情况下,这似乎是 x86_64 上的 Linux.

  • ReadKey may have issues, but certainly not in the common case that you are drying to do, which seems to be Linux on x86_64.

OmniSharp 是一个用于 IDE/文本编辑器的插件,使开发更容易.它提供自动完成和实时语法高亮.运行应用程序时不涉及.

OmniSharp is a plugin for IDEs/text-editors to make development easier. It provides auto completion and real time syntax highlighting. It's not involved when you are running your application.

这篇关于如何在 dotnet 应用程序中创建导航菜单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆