Global Hook Keylogger问题

它将密钥记录到文本框中,因此它是安全的。

问题问题是,当我在虚拟机或我的朋友笔记本电脑上运行它时,它在按下一定数量的键(随机)后挂起。它在我的运行完全正常。

http://sofzh.miximages.com/c%23/29o1im8.jpg

class GlobalKeyboardHook { #region Definition of Structures, Constants and Delegates public delegate int KeyboardHookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam); public struct GlobalKeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } const int WM_KEYDOWN = 0x100; const int WM_KEYUP = 0x101; const int WM_SYSKEYDOWN = 0x104; const int WM_SYSKEYUP = 0x105; const int WH_KEYBOARD_LL = 13; #endregion #region Events public event KeyEventHandler KeyDown; public event KeyEventHandler KeyUp; #endregion #region Instance Variables public List HookedKeys = new List(); IntPtr hookHandle = IntPtr.Zero; #endregion #region DLL Imports [DllImport("kernel32.dll")] static extern IntPtr LoadLibrary(string lpFileName); [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)] static extern IntPtr SetWindowsHookEx(int hookID, KeyboardHookProc callback, IntPtr hInstance, uint threadID); [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)] static extern bool UnhookWindowsHookEx(IntPtr hookHandle); [DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)] static extern int CallNextHookEx(IntPtr hookHandle, int nCode, int wParam, ref GlobalKeyboardHookStruct lParam); #endregion #region Public Methods public int hookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam) { if (nCode >= 0) { Keys key = (Keys)lParam.vkCode; if (HookedKeys.Contains(key) == true) { KeyEventArgs kea = new KeyEventArgs(key); if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && KeyUp != null) { KeyUp(this, kea); } else if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && KeyDown != null) { KeyDown(this, kea); } if (kea.Handled) return 1; } } return CallNextHookEx(hookHandle, nCode, wParam, ref lParam); } public void hook() { IntPtr hInstance = LoadLibrary("user32"); hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0); } public void unhook() { UnhookWindowsHookEx(hookHandle); } #endregion #region Constructors and Destructors public GlobalKeyboardHook() { hook(); } ~GlobalKeyboardHook() { unhook(); } #endregion 

尝试在打开“CallbackOnCollectedDelegate”MDA的情况下调试应用程序(Debug – > Exceptions – > Managed Debugging Assistants – > check“CallbackOnCollectedDelegate”)。

这里常见的错误是,在设置挂钩后,GC会自动收集挂钩过程的委托(它是作为P / Invoke封送到SetWindowsHookEx一部分创建的)。 GC收集代理后,程序在尝试调用回调时崩溃。 这也可以解释随机性。

如果这是您的问题,您将看到如下错误:

对类型为“…”的垃圾收集委托进行了回调。 这可能会导致应用程序崩溃,损坏和数据丢失。 将委托传递给非托管代码时,托管应用程序必须保持它们的活动状态,直到确保它们永远不会被调用。

尝试将您的钩子程序的引用保留为您class级中的成员,例如:

 public delegate int KeyboardHookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam); public int hookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam) { // ... } public void hook() { _hookProc = new KeyboardHookProc(hookProc); IntPtr hInstance = LoadLibrary("user32"); hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, _hookProc, hInstance, 0); } KeyboardHookProc _hookProc;