Почему ReadKey выдает исключение при запуске консольного приложения. net из Git Bash? - PullRequest
3 голосов
/ 19 июня 2020

Это код:

ConsoleKeyInfo cki;

while((cki = Console.ReadKey(true)).Key != ConsoleKey.Escape)
{
    Console.WriteLine(cki.Key);
}

Когда я запускаю его из cmd или powershell с помощью do tnet run, все работает нормально. Однако, когда я запускаю его из Git Bash, он выдает следующее исключение:

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

Ответы [ 2 ]

3 голосов
/ 19 июня 2020

По сути, 100% того, что Мар c сказал в своем ответе.

Боковое примечание к этому: под linux -подобными терминалами (и git - bash является одним из них) типичный (или даже стандартный) способ прерывания интерактивного приложения / скрипта, который в настоящее время блокирует / удерживает консоль, - это нажать Control + C. Консольные приложения с ядром net поддерживают это. Намного проще сделать это с помощью control + c, чем пытаться посмотреть, какие клавиши нажимаются.

IIR C, net -кордные приложения автоматически обнаруживают нажатие control + C и по умолчанию они просто закрываются, и это делает консоль снова доступной для пользователя. Это означает, что не нужно писать дополнительный код, и даже while(true) циклы могут быть остановлены с его помощью (обработчик событий, который управляет + c, запускается в пуле потоков, независимо от того, что основной поток занят).

https://docs.microsoft.com/en-us/dotnet/api/system.console.cancelkeypress?view=netcore-3.1

По умолчанию свойство Cancel имеет значение false, что приводит к завершению выполнения программы при выходе из обработчика событий. Изменение его свойства на true указывает, что приложение должно продолжать выполнение.

3 голосов
/ 19 июня 2020

Предположительно, тогда Git Bash использует перенаправление ввода-вывода - что ему разрешено - а остальные ... нет. Таким образом, решение состоит в том, чтобы использовать Read, а не ReadKey - по крайней мере, если используется перенаправление. Вы, вероятно, можете обнаружить это через Console.IsInputRedirected - и выбрать наиболее полезную стратегию из возможных, но: вы не сможете обнаружить ключи таким же образом, поэтому в этом сценарии вам может потребоваться немного другое взаимодействие с пользователем.

...