Как создать навигационное меню в приложении dotnet? - PullRequest
0 голосов
/ 14 ноября 2018

Я создал консольное приложение, в котором есть меню, которое позволяет мне перемещаться между пунктами меню. Я работаю с логикой навигации в этом методе:

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 все работает хорошо, но когда я запускаю это приложение на моем Linux с systemd, я получаю:

Необработанное исключение: System.InvalidOperationException: Невозможно прочитать ключ, когда какое-либо приложение не имеет консоли или когда ввод с консоли был перенаправлен. Попробуйте Console.Read.

Отображение стека:

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

После некоторых поисков я обнаружил, что эта проблема связана с тем, что метод ReadKey() не полностью совместим с linux . И предложенное решение здесь просто не работает в моем случае, потому что пользователь использовал OminSharp.

Я также попытался установить ReadKey(false), но это не устранило проблему, и я также попытался обработать все вещи внутри UpdateMenu с помощью Console.Read(), но консоль кажется застрявшей.

Обратите внимание, что эта проблема будет возникать только тогда, когда я запускаю свой скрипт в linux supervisor, а не командой по умолчанию, такой как 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

Честно говоря, я не знаю, как я могу это исправить. У кого-нибудь есть идеи?

Заранее спасибо.

1 Ответ

0 голосов
/ 15 ноября 2018

Короткий ответ на то, что вы хотите сделать, это то, что вы просто не можете.

Подумайте об этом: вы пытаетесь создать интерактивную программу (с которой пользователи могут взаимодействовать с помощью клавиатуры). Но вы также делаете его демоном (демон запускает фон и не взаимодействует с пользователями напрямую). Это две противоречивые цели.

Когда systemd (или supervisord, или upstart или действительно любая программа системных служб) запускает ваше приложение как службу, оно не дает ему возможности взаимодействовать с пользователями, так как эти приложения хотят быть демоны - это означает, что пользователи не могут взаимодействовать с ними.

Итак, спросите себя, что вы хотите сделать: хотите ли вы сделать интерактивную программу или нет? Если вы хотите создать интерактивную программу, вы не можете запустить ее через супервизора. Запустите его напрямую через dotnet /path/to/your.dll.

Другие комментарии:

  • ReadKey могут иметь проблемы, но, конечно, не в том общем случае, который вы решаете сделать, который, похоже, Linux на x86_64.

  • OmniSharp - это плагин для IDE / текстовых редакторов, облегчающий разработку. Это обеспечивает автоматическое завершение и подсветку синтаксиса в реальном времени. Он не задействован, когда вы запускаете приложение.

...