在C#中应用HOOK

钩子 (Hook) ,是 Windows 消息处理机制的一个平台 , 应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理 window 消息或特定事件。

关于Hook的详细介绍,在微软的MSDN中有, http://www.microsoft.com/china/community/program/originalarticles/techdoc/hook.mspx

下面是我在C#中来应用Hook:

实现效果:

当用户在TextBox中输入 b 的时候,TextBox 始终显示 a

实现过程:

1、新建一个C#的WindowsApplication

2、在Form1中,添加下面一些变量:

internal enum HookType //枚举,钩子的类型

{

//MsgFilter = -1,

//JournalRecord = 0,

//JournalPlayback = 1,

Keyboard = 2,

//GetMessage = 3,

//CallWndProc = 4,

//CBT = 5,

//SysMsgFilter = 6,

//Mouse = 7,

//Hardware = 8,

//Debug = 9,

//Shell = 10,

//ForegroundIdle = 11,

//CallWndProcRet = 12,

//KeyboardLL = 13,

//MouseLL = 14,

};

IntPtr _nextHookPtr; //记录Hook编号

3、在Form1中引入必须的API

[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId(); //取得当前线程编号的API

[DllImport("User32.dll")]

internal extern static void UnhookWindowsHookEx(IntPtr handle); //取消Hook的API

[DllImport("User32.dll")]

internal extern static IntPtr SetWindowsHookEx( int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID); //设置Hook的API

[DllImport("User32.dll")]

internal extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个Hook的API

4、声明一个实现的委托

internal delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);

5、添加自己的Hook处理过程

IntPtr MyHookProc( int code, IntPtr wparam, IntPtr lparam)

{

if ( code < 0 ) return CallNextHookEx(_nextHookPtr,code, wparam, lparam); // 返回,让后面的程序处理该消息

if ( wparam.ToInt32() == 98 || wparam.ToInt32() == 66 ) // 如果用户输入的是 b

{

this .textBox1.Text = "a";

return (IntPtr) 1; // 直接返回了,该消息就处理结束了

}

else

{

return IntPtr.Zero; // 返回,让后面的程序处理该消息

}

}

6、添加加入Hook链和从Hook链中取消的函数

public void SetHook()

{

if ( _nextHookPtr != IntPtr.Zero ) // 已经勾过了

return ;

HookProc myhookProc = new HookProc(MyHookProc); // 声明一个自己的 Hook 实现函数的委托对象

_nextHookPtr = SetWindowsHookEx(( int )HookType.Keyboard, myhookProc , IntPtr.Zero , GetCurrentThreadId()); // 加到 Hook 链中

}

public void UnHook()

{

if ( _nextHookPtr != IntPtr.Zero )

{

UnhookWindowsHookEx(_nextHookPtr); // 从 Hook 链中取消

_nextHookPtr = IntPtr.Zero;

}

}

7、在Form1的Load事件中添加 SetHook() , 在Form1的closing 事件中添加 UnHook()

private void Form1_Load( object sender, System.EventArgs e)

{

SetHook();

}

private void Form1_Closing( object sender, System.ComponentModel.CancelEventArgs e)

{

UnHook();

}

8、运行

输入 b , 发现 textbox 里面显示的是 a 了!

小结:

这是一个非常简单的Hook应用,当我们在做windows程序的时候,可能会用到这些东西。我正在试图做一个比较通用的类来进行一个封装,以便以后更好的使用。努力ing...

Published At
Categories with Web编程
Tagged with
comments powered by Disqus