首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用标准输入流代替Console.ReadKey

如何使用标准输入流代替Console.ReadKey
EN

Stack Overflow用户
提问于 2019-04-29 05:01:17
回答 1查看 382关注 0票数 1

如何使用Stream.Read()而不是Console.ReadKey()?

代码语言:javascript
复制
while (true)
{
    var c = Console.In.Read();
    Console.WriteLine("input:" + c);
}

但是,只有输入整行时,该值才会返回。

我不想使用Console.ReadKey()来实现这个函数。因为这对测试不好。

那么,如何通过流监视用户的密钥输入呢?或通过其他方法。(当不尽可能多地使用接口时)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-29 08:26:00

.NET框架和.NET核心使用Win32函数ReadConsoleInput来驱动Console.ReadKey()Console.ReadKey()每次从控制台缓冲区读取一些数据。

相反,使用Console.InConsole.OpenStandardInput()调用Win32函数GetStdHandle,然后将句柄封装在私有类__ConsoleStream中,该类在内部使用ReadFileReadConsole Win32函数,具体取决于以下几点。

默认情况下,控制台流配置为ENABLE_ECHO_INPUT,它将您键入的每个字符回显。这需要设置ENABLE_LINE_INPUT

ENABLE_LINE_INPUT的文档声明:

ReadFileReadConsole函数仅在读取回车字符时返回。如果禁用此模式,则当一个或多个字符可用时,函数将返回。

因此,如果需要使用ReadFileReadConsole的流,则需要禁用这两个标志的控制台句柄。这样做是可以的:

代码语言:javascript
复制
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);
}

这将为您提供一个流,它允许您一次读取一个字符,即使还没有输入整行。

注意,这将不会将每个字符打印到屏幕上。如果你还想要的话,你就得自己回音了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55897200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档