如何修复 C# 控制台应用程序中的错误 KeyEventHandler?
Posted
技术标签:
【中文标题】如何修复 C# 控制台应用程序中的错误 KeyEventHandler?【英文标题】:How to fix error KeyEventHandler in c# console application? 【发布时间】:2020-11-09 02:48:21 【问题描述】:我有个问题,在我的winform应用程序中执行这段代码的时候,运行正常,但是在控制台运行的时候报错,好像KeyEventHandler只用在winform中,是的,可以在控制台替换什么应用。这是我的钩子函数:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace Websevice_Core_Console
class Y2KeyboardHook
#region Win32 API Functions and Constants
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
KeyboardHookDelegate lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x101;
#endregion
private KeyboardHookDelegate _hookProc;
private IntPtr _hookHandle = IntPtr.Zero;
public delegate IntPtr KeyboardHookDelegate(int nCode, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
public struct KeyboardHookStruct
public int VirtualKeyCode;
public int ScanCode;
public int Flags;
public int Time;
public int ExtraInfo;
#region Keyboard Events
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
#endregion
// destructor
~Y2KeyboardHook()
Uninstall();
public void Install()
_hookProc = KeyboardHookProc;
_hookHandle = SetupHook(_hookProc);
if (_hookHandle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
private IntPtr SetupHook(KeyboardHookDelegate hookProc)
IntPtr hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
if (nCode >= 0)
KeyboardHookStruct kbStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
if (wParam == (IntPtr)WM_KEYDOWN)
if (KeyDown != null)
KeyDown(null, new KeyEventArgs((Keys)kbStruct.VirtualKeyCode));
else if (wParam == (IntPtr)WM_KEYUP)
if (KeyUp != null)
KeyUp(null, new KeyEventArgs((Keys)kbStruct.VirtualKeyCode));
return CallNextHookEx(_hookHandle, nCode, wParam, lParam);
public void Uninstall()
UnhookWindowsHookEx(_hookHandle);
这是我的使用方法:
_y2KeyboardHook.KeyDown += (sender, e) =>// ghi nhan thong tin tu ban phim
if (e.KeyCode.ToString() != "")
Console.WriteLine("Hello "+KeyCode);
我在 2 行收到一条错误消息
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
谁能帮帮我,非常感谢!
【问题讨论】:
【参考方案1】:鉴于您发布的代码和含糊的“我收到一条错误消息”(这不是一个实际问题,也不是一个有用的问题陈述......总是具体),您似乎没有引用System.Windows.Forms.dll
。另一方面,如果您没有引用 Winforms 程序集,则不清楚为什么您在使用 KeyEventArgs
时也不会收到错误,因为这是在同一个程序集中定义的。
也就是说,假设您在使用 KeyEventHandler
时遇到的错误只是它没有定义,您可以定义相同的类型供您自己使用:
public delegate void KeyEventHandler(object sender, KeyEventArgs e);
即,只需从 the documentation 复制委托类型声明。
现在,所有 都说,如果您没有引用 Winforms 程序集,并且您收到 KeyEventArgs
类型的错误消息,正如预期的那样,您可能要考虑不复制此方法的 Winforms 实现,而只需使用您自己的事件处理程序声明您自己的事件 args 类型。您返回的唯一内容是虚拟键代码,因此您不妨为此定义自己的类型:
class KeyboardHookEventArgs : EventArgs
public int VirtualKeyCode get;
public KeyboardHookEventArgs(int virtualKeyCode)
VirtualKeyCode = virtualKeyCode;
…然后是事件:
public event EventHandler<KeyboardHookEventArgs> KeyDown;
public event EventHandler<KeyboardHookEventArgs> KeyUp;
您在哪里创建像 new KeyboardHookEventArgs(kbStruct.VirtualKeyCode)
这样的 args 对象。
请注意,您的事件引发实现不是线程安全的。在 C# 中使用空条件运算符会更安全,也更惯用,例如:
if (wParam == (IntPtr)WM_KEYDOWN)
KeyDown?.Invoke(this, new KeyboardHookEventArgs(kbStruct.VirtualKeyCode));
您还应该为sender
传递一个正确的值,即this
,如上所示。如果您希望事件没有发送者,那么它(以及班级的其他成员)应该只是 static
。
【讨论】:
“我无法将键码写入控制台屏幕”——这听起来像是一个全新的问题。您提出的 这个 问题与缺少的类型有关。如果您在执行此操作时遇到其他问题,则需要将其作为一个或多个新问题发布。以上是关于如何修复 C# 控制台应用程序中的错误 KeyEventHandler?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 CORS 错误:ASP .NET C# 中的 MethodDisallowedByPreflightResponse