我有一个控制台应用程序,我知道如何捕获用户输入,但我希望用户能够随时按Ctrl+X
并捕获它(重置应用程序)。
如何捕获任何用户输入?
精化
Console
对象有三种输入法:
int Read()
int ReadKey()
string ReadLine()
我需要能够捕获普通用户输入,即用户输入,并将其显示为用户类型。
此外,用户可以随时按Ctrl+X
,这将调用Reset()
方法。
答案 0 :(得分:2)
HotKeyManager的原始代码来自这篇文章: Global keyboard capture in C# application
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace ConsoleHotKey
{
public static class HotKeyManager
{
public static event EventHandler<HotKeyEventArgs> HotKeyPressed;
public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
{
_windowReadyEvent.WaitOne();
int id = System.Threading.Interlocked.Increment(ref _id);
_wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, id, (uint)modifiers, (uint)key);
return id;
}
public static void UnregisterHotKey(int id)
{
_wnd.Invoke(new UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal), _hwnd, id);
}
delegate void RegisterHotKeyDelegate(IntPtr hwnd, int id, uint modifiers, uint key);
delegate void UnRegisterHotKeyDelegate(IntPtr hwnd, int id);
private static void RegisterHotKeyInternal(IntPtr hwnd, int id, uint modifiers, uint key)
{
RegisterHotKey(hwnd, id, modifiers, key);
}
private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)
{
UnregisterHotKey(_hwnd, id);
}
private static void OnHotKeyPressed(HotKeyEventArgs e)
{
if (HotKeyManager.HotKeyPressed != null)
{
HotKeyManager.HotKeyPressed(null, e);
}
}
private static volatile MessageWindow _wnd;
private static volatile IntPtr _hwnd;
private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
static HotKeyManager()
{
Thread messageLoop = new Thread(delegate()
{
Application.Run(new MessageWindow());
});
messageLoop.Name = "MessageLoopThread";
messageLoop.IsBackground = true;
messageLoop.Start();
}
private class MessageWindow : Form
{
public MessageWindow()
{
_wnd = this;
_hwnd = this.Handle;
_windowReadyEvent.Set();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_HOTKEY)
{
HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
HotKeyManager.OnHotKeyPressed(e);
}
base.WndProc(ref m);
}
protected override void SetVisibleCore(bool value)
{
// Ensure the window never becomes visible
base.SetVisibleCore(false);
}
private const int WM_HOTKEY = 0x312;
}
[DllImport("user32", SetLastError = true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private static int _id = 0;
}
public class HotKeyEventArgs : EventArgs
{
public readonly Keys Key;
public readonly KeyModifiers Modifiers;
public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
{
this.Key = key;
this.Modifiers = modifiers;
}
public HotKeyEventArgs(IntPtr hotKeyParam)
{
uint param = (uint)hotKeyParam.ToInt64();
Key = (Keys)((param & 0xffff0000) >> 16);
Modifiers = (KeyModifiers)(param & 0x0000ffff);
}
}
[Flags]
public enum KeyModifiers
{
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
NoRepeat = 0x4000
}
}
以下是您的请求的用法:
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using ConsoleHotKey;
namespace ConsoleTester
{
class Program
{
static bool exitApp = false;
static void Main(string[] args)
{
HotKeyManager.RegisterHotKey(Keys.X, KeyModifiers.Control);
HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(HotKeyManager_HotKeyPressed);
//this loop is only to keep app from exiting...
while (!exitApp)
{
Console.WriteLine("Press Ctrl+X to exit!");
System.Threading.Thread.Sleep(1000);
//TODO: write you code...
}
}
static void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e)
{
Console.WriteLine("Aplication will exit!");
//TODO: restart yor app or in this case force exit...
exitApp = true;
}
}
}
以下是有关如何重新启动应用的附加代码:
System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo();
Info.FileName = System.Reflection.Assembly.GetEntryAssembly().Location;
System.Diagnostics.Process.Start(Info);