我正在尝试制作一个程序,通过在 WH_DEBUG 上安装全局 Hook 来检测我的系统上的键盘记录器。我的问题是,GetModuleHandle(似乎还有所有其他更晦涩的获取模块句柄的方法)返回 null。我希望这里有人能够阐明这一情况。
MainForm.cs:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace MouseTimer
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
public static void log(String ltxt)
{
((MainForm)Application.OpenForms[0]).richTextBox1.Text += ltxt+"\n";
((MainForm)Application.OpenForms[0]).richTextBox1.SelectionStart = ((MainForm)Application.OpenForms[0]).richTextBox1.Text.Length;
((MainForm)Application.OpenForms[0]).richTextBox1.ScrollToCaret();
}
public int DbgEvt(int code, IntPtr wParam, IntPtr lParam)
{
log("DBGEVT: "+wParam.ToString());
return 0;
}
void MainFormLoad(object sender, EventArgs e)
{
WindowsHook wh = new WindowsHook(HookType.WH_DEBUG, DbgEvt);
wh.Install();
}
}
}
WindowsHook.cs:
public class WindowsHook
{
public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
protected IntPtr m_hhook = IntPtr.Zero;
protected HookProc m_filterFunc = null;
protected HookType m_hookType;
public delegate void HookEventHandler(object sender, HookEventArgs e);
public event HookEventHandler HookInvoked;
protected void OnHookInvoked(HookEventArgs e)
{
if (HookInvoked != null)
HookInvoked(this, e);
}
public WindowsHook(HookType hook)
{
m_hookType = hook;
m_filterFunc = new HookProc(this.CoreHookProc);
}
public WindowsHook(HookType hook, HookProc func)
{
m_hookType = hook;
m_filterFunc = func;
}
protected int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code < 0)
return CallNextHookEx(m_hhook, code, wParam, lParam);
HookEventArgs e = new HookEventArgs();
e.HookCode = code;
e.wParam = wParam;
e.lParam = lParam;
OnHookInvoked(e);
return CallNextHookEx(m_hhook, code, wParam, lParam);
}
public void Install()
{
using (Process p = Process.GetCurrentProcess())
using (ProcessModule m = p.MainModule)
{
m_hhook = SetWindowsHookEx(m_hookType, m_filterFunc,
GetModuleHandle(m.ModuleName), 0);
}
}
public void Uninstall()
{
UnhookWindowsHookEx(m_hhook);
m_hhook = IntPtr.Zero;
}
public bool IsInstalled
{
get{ return m_hhook != IntPtr.Zero; }
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
protected static extern IntPtr SetWindowsHookEx(HookType code,
HookProc func,
IntPtr hInstance,
int threadID);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
protected static extern int UnhookWindowsHookEx(IntPtr hhook);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
protected static extern int CallNextHookEx(IntPtr hhook,
int code, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
问题是,当我尝试(低级)鼠标 Hook 时,它在没有模块句柄的情况下 Hook 得很好。所以我不确定问题是什么。有人可以帮忙吗?
提前致谢,
迈克
最佳答案
.Net 不支持全局 Hook 。
请参见此处:http://support.microsoft.com/kb/318804?wa=wsignin1.0
我引用的内容是:
Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework. To install a global hook, a hook must have a native DLL export to inject itself in another process that requires a valid, consistent function to call into. This behavior requires a DLL export. The .NET Framework does not support DLL exports. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.
关于C# - 没有模块句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15658650/