C#_HOOK

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

所以你在做程序时,不要因为调试失败而对这个函数有怀疑,编一个 Release 版本的程序,独 立运行再试一下。我使用的环境是 VS2005 + Vista。
接收消息的函数
1
private int HookCallback(int code, IntPtr wParam, ref KBDLLHOOKSTRUC
Reader 会在你截取之前获得键盘。 HookProc KeyBoardHookProcedure; //键盘 Hook 结构函数 [StructLayout(LayoutKind.Sequential)] public class KeyBoardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } #region DllImport //设置钩子 [DllImport("user32.dll")] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int
看一下定义
1
[DllImport("user32.dll")]
2
private static extern IntPtr SetWindowsHookEx(
3
HookType code, HookProc func, IntPtr instance, int threadID);
4
5
[DllImport("user32.dll")]
C#中实现 Hook
目前的程序中想要添加 Hook,截获键盘按键消息,所以上网找了一下关于 C#下 Hook 的东西。 发现很多人都在说在 C#中添加 Hook 不成功和不稳定,而建议使用 C++封一个 Dll 给 C#使用。
,可喜的是最后我还是成功的在程序中使用 C#添加了 Hook,经过测试还是没有什么问题 的。 进行 Hook 需要使用三个 API 函数 SetWindowsHookEx 进行 Hook 的注册 UnhookWindowsHookEx 取消已经注册的 Hook CallNextHookEx 将消息传递给下一个 Hook 函数
13
// Windows.Forms.Control.ModifierKeys instead of Keyboard.Modifier
s
14
// since Keyboard.Modifiers does not correctly get the state of the
15
// modifier keys when the application does not have focus
2
public event HookEventHandler KeyDown;
3
public event HookEventHandler KeyUp;
4
因为要接收的是键盘的消息所以要定义一些消息,和我们要接收的结构。
1 public class HookEventArgs : EventArgs
2
6
private static extern int UnhookWindowsHookEx(IntPtr hook);
7
8
[DllImport("user32.dll")]
9
private static extern int CallNextHookEx(
10
IntPtr hook, int code, IntPtr wParam, ref KBDLLHOOKSTRUCT lPara
13
WH_SHELL = 10,
14
WH_FOREGROUNDIDLE = 11,
15
WH_CALLWNDPROCRET = 12,
16
WH_KEYBOARD_LL = 13,
17
WH_MOUSE_LL = 14
18
}
19
20
public struct KBDLLHOOKSTRUCT
21
{
22
public UInt32 vkCode;
5
public Keys Key;
6

public bool Alt;
7
public bool Control;
8
public bool Shift;
9
10
public HookEventArgs(UInt32 keyCode)
11
{
12
// detect what modifier keys are pressed, using
T lParam)
2
{
3
if (code < 0)
4
return CallNextHookEx(_hookHandle, code, wParam, ref lParam);
5
6
if ((lParam.flags & 0x80) != 0 && this.KeyUp != null)
7
this.KeyUp(this, new HookEventArgs(lParam.vkCode));
16
this.Key = (Keys)keyCode;
17
this.Alt = (System.Windows.Forms.Control.ModifierKeys & Keys.Alt) !
= 0;
18
this.Control = (System.Windows.Forms.Control.ModifierKeys & Keys.
m);
我们需要定义一个 delegate 来接收消息
1
private delegate int HookProc(int code, IntPtr wParam, ref KBDLLHOOKS
TRUCT lParam);
定义两个 event 提供给外界使用
1
public delegate void HookEventHandler(object sender, HookEventArgs e);
Control) != 0;
19
this.Shift = (System.Windows.Forms.Control.ModifierKeys & Keys.Shi
ft) != 0;
20
}
21 }
1
private enum HookType : int
2
{
3
WH_JOURNALRECORD = 0,

还有_hookFunction = new HookProc(HookCallback); 其实最关键的是 Marshal.GetHINSTANCE(list[0])得到当前程序的 instance,这样这个 Hoo
k 就是全局的 Hook,这个位置也可以是 null,这样就不是全局 Hook。
有个很奇怪的现象就是这个函数,在调试状态执行不能成功,而做成 Release 以后运行成功,
4
WH_JOURNALPLAYBACK = 1,
5
WH_KEYBOARD = 2,
6
WH_GETMESSAGE = 3,
7
WH_CALLWNDPROC = 4,
8
WH_CBT = 5,
9
WH_SYSMSGFILTER = 6,
10
WH_MOUSE = 7,
11
WH_HARDWARE = 8,
12
WH_DEBUG = 9,
8
9
if ((lParam.flags & 0x80) == 0 && this.KeyDown != null)
10
{
11
this.KeyDown(this, new HookEventArgs(lParam.vkCode));
12
if (lParam.vkCode == 44)
13
{
14
return 1;
8
9
_hookHandle = SetWindowsHookEx(_hookType,
10
_hookFunction, Marshal.GetHINSTANCE(list[0]), 0);
11
12
}
哦,还有 HookType _hookType = HookType.WH_KEYBOARD_LL; 因为要截获键盘消
23
public UInt32 scanCode;
24
public UInt32 flags;
25
public UInt32 time;
26
public IntPtr extraInfo;
27
}
关键的在这里 注册 Hook
1
private void Install()
2
{
3
if (_hookHandle != IntPtr.Zero)
namespace WindowsApplication1 {
/// <summary> /// Description of MainForm. /// </summary> public partial class Form4 : Form { //委托 public delegate int HookProc(int nCode, int wParam, IntPtr lParam); static int hHook = 0; public const int WH_KEYBOARD_LL = 13; //LowLevel 键盘截获,如果是 WH_KEYBOARD=2,并不能对系统键盘截取,Acrobat
15
}
16
}
17
18
return CallNextHookEx(_hookHandle, code, wParam, ref lParam);
19
}
这里会区分 KeyUp 和 KeyDown,注意一定要调用 CallNextHookEx,这样会将这个消息在系
统中继续传递,这很重要。除非你想阻止这个消息,也不希望其他程序再处理这个消息。
{
3
// using Windows.Forms.Keys instead of Input.Key since the Forms.Key
s maps
4
// to the Win32 KBDLLHOOKSTRUCT virtual key member, where Input.K
ey does not
threadId); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =
CallingConvention.StdCall)] //抽掉钩子 public static extern bool UnhookWindowsHookEx(int idHook); [DllImport("user32.dll")] //调用下一个钩子 public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll")] public static extern int GetCurrentThreadId();
4
return;
5
6
Module[] list = System.Reflection.Assembly.GetExecutingAssembly().
GetModules();
7
System.Diagnostics.Debug.Assert(list != null && list.Length > 0);
下面最后的操作,释放注册。
1
private void Uninstall()
2
{
3
if (_hookHandle != IntPtr.Zero)
4
{
5
UnhookWindowsHookEx(_hookHandle);
6
_hookHandle = IntPtr.Zero;
7
}
8
}
Ok,完成了。
类似的问题好多............前几天就有人文这个问题。你也不说明什么问题就发代码... 新建一个 form4 窗体.增加 2 个 button,增加事件。。然后复制代码 其实不一样的地方就是红色的地方 using System; using System.Collections.Generic; using ponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Reflection; using System.Diagnostics;
相关文档
最新文档