如何使用C#控制台应用程序读取按键? (带有Shift,Alt,Ctrl)
我有.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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论