如何使用Stream.Read()而不是Console.ReadKey()?
while (true)
{
var c = Console.In.Read();
Console.WriteLine("input:" + c);
}但是,只有输入整行时,该值才会返回。
我不想使用Console.ReadKey()来实现这个函数。因为这对测试不好。
那么,如何通过流监视用户的密钥输入呢?或通过其他方法。(当不尽可能多地使用接口时)
发布于 2019-04-29 08:26:00
.NET框架和.NET核心使用Win32函数ReadConsoleInput来驱动Console.ReadKey(),Console.ReadKey()每次从控制台缓冲区读取一些数据。
相反,使用Console.In或Console.OpenStandardInput()调用Win32函数GetStdHandle,然后将句柄封装在私有类__ConsoleStream中,该类在内部使用ReadFile或ReadConsole Win32函数,具体取决于以下几点。
默认情况下,控制台流配置为ENABLE_ECHO_INPUT,它将您键入的每个字符回显。这需要设置ENABLE_LINE_INPUT。
ENABLE_LINE_INPUT的文档声明:
ReadFile或ReadConsole函数仅在读取回车字符时返回。如果禁用此模式,则当一个或多个字符可用时,函数将返回。
因此,如果需要使用ReadFile或ReadConsole的流,则需要禁用这两个标志的控制台句柄。这样做是可以的:
static class Win32Console
{
public static Stream GetConsoleStreamWithImmediateInput()
{
var handle = GetStdHandle(STD_INPUT_HANDLE);
if (handle.IsInvalid) throw new Win32Exception();
try
{
if (!GetConsoleMode(handle, out var mode)) throw new Win32Exception();
mode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
if (!SetConsoleMode(handle, mode)) throw new Win32Exception();
}
catch
{
handle.Close();
throw;
}
return new FileStream(handle, FileAccess.Read);
}
const int STD_INPUT_HANDLE = -10;
const int ENABLE_LINE_INPUT = 0x0002;
const int ENABLE_ECHO_INPUT = 0x0004;
[DllImport("Kernel32.dll", SetLastError = true)]
static extern SafeFileHandle GetStdHandle(int nStdHandle);
[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetConsoleMode(SafeFileHandle hConsoleHandle, out int mode);
[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetConsoleMode(SafeFileHandle hConsoleHandle, int mode);
}这将为您提供一个流,它允许您一次读取一个字符,即使还没有输入整行。
注意,这将不会将每个字符打印到屏幕上。如果你还想要的话,你就得自己回音了。
https://stackoverflow.com/questions/55897200
复制相似问题