如何使用C#控制台应用程序读取按键? (带有Shift,Alt,Ctrl)

发布于 2025-02-01 11:30:19 字数 4171 浏览 4 评论 0原文

我有.NET 2.0控制台应用程序。

如果在10秒内按下键,我只想添加其他方法。使用计时器。

我想添加这样的添加

        var start = DateTime.Now;
        while ((DateTime.Now - start).TotalSeconds < 5)
        {
            if ((Console.KeyAvailable ))
            {
                var key = KeyHandler.ReadKey();
                Console.WriteLine($"Event:{key.KeyPressType} Key:{key.Key.Key}");
                Console.WriteLine("pressed");
                
            }
            else
            {
                Console.WriteLine("NOT pressed");
            }

        }
        Console.WriteLine("Done");

,但将上行代码添加到以下代码中。 程序未检测到ALT,CTRL或Shift键是按下的。

这是没有计时器的工作代码。

我只想停止程序10秒。检测任何键是否按下。恢复程序到下一个而不按任何键。

这用于键盘的不良键检测。

我不想使用thread.sleep。因为那将阻止小秒。

using System.Runtime.InteropServices;
using static Win32Native;
using System;
using System.IO;
using System.Diagnostics;
using System.Timers;

class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello");
        while (true)
        {
            var key = KeyHandler.ReadKey();
            Console.WriteLine($"Event:{key.KeyPressType} Key:{key.Key.Key}");
        }
    }
}

enum KeyPressType { KeyUp, KeyDown, Unknown }
class SimpleKeyRecord { public KeyPressType KeyPressType; public ConsoleKeyInfo Key; }
class KeyHandler
{
    static IntPtr _consoleInputHandle = Win32Native.GetStdHandle(Win32Native.STD_INPUT_HANDLE);
    
    public static SimpleKeyRecord ReadKey()
    {
        var result = new SimpleKeyRecord();
        Win32Native.InputRecord ir;
        int numEventsRead;

        if (!Win32Native.ReadConsoleInput(_consoleInputHandle, out ir, 1, out numEventsRead) || numEventsRead == 0)
        {
            throw new InvalidOperationException();
        }

        if (ir.eventType != 1)  // see https://learn.microsoft.com/en-us/windows/console/input-record-str
        {
            result.KeyPressType = KeyPressType.Unknown; // Focus/Mouse/Menu event.
            return result;
        }

        result.KeyPressType = ir.keyEvent.keyDown ? KeyPressType.KeyDown : KeyPressType.KeyUp;

        ControlKeyState state = (ControlKeyState)ir.keyEvent.controlKeyState;
        bool shift = (state & ControlKeyState.ShiftPressed) != 0;
        bool alt = (state & (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0;
        bool control = (state & (ControlKeyState.LeftCtrlPressed | ControlKeyState.RightCtrlPressed)) != 0;

        result.Key = new ConsoleKeyInfo((char)ir.keyEvent.uChar, (ConsoleKey)ir.keyEvent.virtualKeyCode, shift, alt, control);

        short virtualKeyCode = ir.keyEvent.virtualKeyCode;

        return result;
    }
}

class Win32Native
{
    public const int STD_INPUT_HANDLE = -10;

    [DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern IntPtr GetStdHandle(int whichHandle);
    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern bool ReadConsoleInput(IntPtr hConsoleInput, out InputRecord buffer, int numInputRecords_UseOne, out int numEventsRead);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    internal struct InputRecord
    {
        internal short eventType;
        internal KeyEventRecord keyEvent;
    }

    // Win32's KEY_EVENT_RECORD
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    internal struct KeyEventRecord
    {
        internal bool keyDown;
        internal short repeatCount;
        internal short virtualKeyCode;
        internal short virtualScanCode;
        internal char uChar; // Union between WCHAR and ASCII char
        internal int controlKeyState;
    }

    [Flags]
    internal enum ControlKeyState
    {
        RightAltPressed = 0x0001,
        LeftAltPressed = 0x0002,
        RightCtrlPressed = 0x0004,
        LeftCtrlPressed = 0x0008,
        ShiftPressed = 0x0010,
        NumLockOn = 0x0020,
        ScrollLockOn = 0x0040,
        CapsLockOn = 0x0080,
        EnhancedKey = 0x0100
    }
}
```````````

I have .NET 2.0 Console Application.

I just Want to add if else method if key was pressed within 10 seconds. Using Timer.

I want to add like this

        var start = DateTime.Now;
        while ((DateTime.Now - start).TotalSeconds < 5)
        {
            if ((Console.KeyAvailable ))
            {
                var key = KeyHandler.ReadKey();
                Console.WriteLine(
quot;Event:{key.KeyPressType} Key:{key.Key.Key}");
                Console.WriteLine("pressed");
                
            }
            else
            {
                Console.WriteLine("NOT pressed");
            }

        }
        Console.WriteLine("Done");

But Adding upside code into following code.
Program not detecting if ALT,CTRL Or Shift key pressed.

Here is working code without timers.

I just want to stop program for 10 seconds. Detect any key was pressed or not. Resume program to next without Pressing any key.

This is used for bad key detection of keyboard.

I dont want to use Thread.Sleep . Because that will block small seconds.

using System.Runtime.InteropServices;
using static Win32Native;
using System;
using System.IO;
using System.Diagnostics;
using System.Timers;

class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello");
        while (true)
        {
            var key = KeyHandler.ReadKey();
            Console.WriteLine(
quot;Event:{key.KeyPressType} Key:{key.Key.Key}");
        }
    }
}

enum KeyPressType { KeyUp, KeyDown, Unknown }
class SimpleKeyRecord { public KeyPressType KeyPressType; public ConsoleKeyInfo Key; }
class KeyHandler
{
    static IntPtr _consoleInputHandle = Win32Native.GetStdHandle(Win32Native.STD_INPUT_HANDLE);
    
    public static SimpleKeyRecord ReadKey()
    {
        var result = new SimpleKeyRecord();
        Win32Native.InputRecord ir;
        int numEventsRead;

        if (!Win32Native.ReadConsoleInput(_consoleInputHandle, out ir, 1, out numEventsRead) || numEventsRead == 0)
        {
            throw new InvalidOperationException();
        }

        if (ir.eventType != 1)  // see https://learn.microsoft.com/en-us/windows/console/input-record-str
        {
            result.KeyPressType = KeyPressType.Unknown; // Focus/Mouse/Menu event.
            return result;
        }

        result.KeyPressType = ir.keyEvent.keyDown ? KeyPressType.KeyDown : KeyPressType.KeyUp;

        ControlKeyState state = (ControlKeyState)ir.keyEvent.controlKeyState;
        bool shift = (state & ControlKeyState.ShiftPressed) != 0;
        bool alt = (state & (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0;
        bool control = (state & (ControlKeyState.LeftCtrlPressed | ControlKeyState.RightCtrlPressed)) != 0;

        result.Key = new ConsoleKeyInfo((char)ir.keyEvent.uChar, (ConsoleKey)ir.keyEvent.virtualKeyCode, shift, alt, control);

        short virtualKeyCode = ir.keyEvent.virtualKeyCode;

        return result;
    }
}

class Win32Native
{
    public const int STD_INPUT_HANDLE = -10;

    [DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern IntPtr GetStdHandle(int whichHandle);
    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern bool ReadConsoleInput(IntPtr hConsoleInput, out InputRecord buffer, int numInputRecords_UseOne, out int numEventsRead);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    internal struct InputRecord
    {
        internal short eventType;
        internal KeyEventRecord keyEvent;
    }

    // Win32's KEY_EVENT_RECORD
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    internal struct KeyEventRecord
    {
        internal bool keyDown;
        internal short repeatCount;
        internal short virtualKeyCode;
        internal short virtualScanCode;
        internal char uChar; // Union between WCHAR and ASCII char
        internal int controlKeyState;
    }

    [Flags]
    internal enum ControlKeyState
    {
        RightAltPressed = 0x0001,
        LeftAltPressed = 0x0002,
        RightCtrlPressed = 0x0004,
        LeftCtrlPressed = 0x0008,
        ShiftPressed = 0x0010,
        NumLockOn = 0x0020,
        ScrollLockOn = 0x0040,
        CapsLockOn = 0x0080,
        EnhancedKey = 0x0100
    }
}
```````````

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文