为什么 ReadKey 在 运行 来自 Git Bash 的 .net-core 控制台应用程序时抛出异常?
Why ReadKey throws exception while running a .net-core console app from Git Bash?
这是代码:
ConsoleKeyInfo cki;
while((cki = Console.ReadKey(true)).Key != ConsoleKey.Escape)
{
Console.WriteLine(cki.Key);
}
当我 运行 从 cmd 或 powershell 使用 dotnet 运行 时,一切正常。然而,当我 运行 它来自 Git Bash 它抛出以下异常:
Unhandled exception. System.InvalidOperationException: Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read.
那么,据推测,Git Bash 正在使用 IO 重定向——这是允许的——而其他人……不是。那么,解决方案是使用 Read
而不是 ReadKey
- 至少在进行重定向时是这样。您可能可以通过 Console.IsInputRedirected
检测 - 并尽可能选择最有用的策略,但是:您将无法检测 keys 以相同的方式,因此在这种情况下您可能需要稍微不同的用户体验。
基本上,马克在他的回答中所说的 100%。
旁注:在类似 linux 的终端(git-bash 是其中之一)下,典型的(甚至是标准的)中止交互式 application/script 当前 blocks/holds 控制台正在按 Control+C。 net-core 控制台应用程序支持这一点。通过 control+c 完成它比试图查看正在按下的键要容易得多。
IIRC,net-core 应用程序自动检测按下 control+C,默认情况下它们只是退出,这让用户可以再次使用控制台。这意味着不需要编写额外的代码,甚至 while(true)
循环都可以因此而停止(处理 control+c 的事件处理程序在线程池中 运行,无论主线程是忙)。
https://docs.microsoft.com/en-us/dotnet/api/system.console.cancelkeypress?view=netcore-3.1
By default, the Cancel property is false, which causes program execution to terminate when the event handler exits. Changing its property to true specifies that the application should continue to execute.
如果我们在 window 调整大小时处理符文宽度大于 1 的 unicode,这仍然会在 OS、Windows
和 Linux
上发生使用 Net5.0.
这是代码:
ConsoleKeyInfo cki;
while((cki = Console.ReadKey(true)).Key != ConsoleKey.Escape)
{
Console.WriteLine(cki.Key);
}
当我 运行 从 cmd 或 powershell 使用 dotnet 运行 时,一切正常。然而,当我 运行 它来自 Git Bash 它抛出以下异常:
Unhandled exception. System.InvalidOperationException: Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read.
那么,据推测,Git Bash 正在使用 IO 重定向——这是允许的——而其他人……不是。那么,解决方案是使用 Read
而不是 ReadKey
- 至少在进行重定向时是这样。您可能可以通过 Console.IsInputRedirected
检测 - 并尽可能选择最有用的策略,但是:您将无法检测 keys 以相同的方式,因此在这种情况下您可能需要稍微不同的用户体验。
基本上,马克在他的回答中所说的 100%。
旁注:在类似 linux 的终端(git-bash 是其中之一)下,典型的(甚至是标准的)中止交互式 application/script 当前 blocks/holds 控制台正在按 Control+C。 net-core 控制台应用程序支持这一点。通过 control+c 完成它比试图查看正在按下的键要容易得多。
IIRC,net-core 应用程序自动检测按下 control+C,默认情况下它们只是退出,这让用户可以再次使用控制台。这意味着不需要编写额外的代码,甚至 while(true)
循环都可以因此而停止(处理 control+c 的事件处理程序在线程池中 运行,无论主线程是忙)。
https://docs.microsoft.com/en-us/dotnet/api/system.console.cancelkeypress?view=netcore-3.1
By default, the Cancel property is false, which causes program execution to terminate when the event handler exits. Changing its property to true specifies that the application should continue to execute.
如果我们在 window 调整大小时处理符文宽度大于 1 的 unicode,这仍然会在 OS、Windows
和 Linux
上发生使用 Net5.0.