我在桌面应用程序中使用键盘低级挂钩来监视用户活动。我用于挂钩的代码如下。在这段代码中(据我所知),当我必须开始监控用户活动时,我称之为SetHook()
安装钩子,我可以监控键盘上按下的键。当我想停止捕获键时,我只需调用 UnHook() 方法。
问题是当我的应用程序启动(SetHook()
尚未调用方法)时,我的应用程序会自动安装挂钩,它会减慢系统速度。系统每 1 分钟挂起 2-3 秒。
为了诊断问题,我注释掉了下面提到的所有代码和安装的应用程序。现在系统工作得很好。
我不确定为什么会这样?
- 为什么我的应用程序开始捕获密钥,即使我还没有调用
SetHook()
方法? - 有没有其他方法可以在不使用钩子的情况下捕获全局键?
挂钩代码:
public static class WinKeyCapture5 {
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
public static DateTime LastKeyPressTime;
public static void SetHook()
{
SetHook(_proc);
}
public static void UnHook()
{
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private static IntPtr _hookID = IntPtr.Zero;
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
//if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
//{
int vkCode = Marshal.ReadInt32(lParam);
//if (vkCode == 44)
//ScreenCapture.Load();
LastKeyPressTime = System.DateTime.Now;
//}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}