c#

位置:IT落伍者 >> c# >> 浏览文章

纯C#钩子实现及应用


发布日期:2022年05月13日
 
纯C#钩子实现及应用

要实现系统钩子其实很简单调用三个Win的API即可

SetWindowsHookEx 用于设置钩子(设立一道卡子盘查需要的信息)

[DllImport( userdll CallingConvention = CallingConventionStdCall )]

public static extern IntPtr SetWindowsHookEx ( WH_Codes idHook HookProc lpfn

IntPtr pInstance int threadId );

CallNextHookEx 用于传递钩子(消息是重要的所以从哪里来就应该回到哪里去除非你决定要封锁消息)

[DllImport( userdll CallingConvention = CallingConventionStdCall )]

public static extern int CallNextHookEx ( IntPtr pHookHandle int nCode

Int wParam IntPtr lParam );

UnhookWindowsHookEx 卸载钩子(卸载很重要卡子设多了会造成拥堵)

[DllImport( userdll CallingConvention = CallingConventionStdCall )]

public static extern bool UnhookWindowsHookEx ( IntPtr pHookHandle );

在《HOW TO在 Visual C# NET 中设置窗口挂钩》一文中有如下描述NET 框架中不支持全局挂钩

您无法在 Microsoft NET 框架中实现全局挂钩若要安装全局挂钩挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中这需要一个 DLL 导出NET 框架不支持这一点托管代码没有让函数指针具有统一的值这一概念因为这些函数是动态构建的代理网上查找了很多代码大都另外包含了一个C++的DLL用于标识包含lpfn所指的子程的DLL似乎也验证了这一说法

但实际上并非如此使用如下代码即可实现全局钩子

IntPtr pInstance = MarshalGetHINSTANCE( AssemblyGetExecutingAssembly()ManifestModule );

WinAPISetWindowsHookEx( WH_MOUSE_LLm_MouseHookProcedure pInstance );注ManifestModule属性是Net Framework 中新增加的所以当你依然使用Net Framework x的时候可以使用GetModules方法获取当前程序集的所有模块然后用其中的一个作为GetHINSTAN方法的参数来获得合适的句柄指针

钩子应用DEMO-屏幕放大器

点击下载可执行文件(Shift + Esc 退出程序)

点击下载源文件

所谓屏幕放大器类似与WINDOWS系统中的辅助工具中的放大镜

前两天在找资料的时候突然发现在Graphics类多了一个CopyFromScreen方法可以直接实现屏幕抓取于是有了做屏幕放大器的想法

首先我定义了是SKHOOK类来截取键盘及鼠标

由于需要获得全局的鼠标消息来确定截屏位置同时要建立一个全局的快捷键来退出程序所以只能用上面说的钩子来实现

然后我通过鼠标点来设置采样区域以及窗体的位置

采样区域为鼠标点为中心的*的矩形区域窗体位置只实现了简单的鼠标跟随同时保证了和采样区域不重叠

另外我使用了一个BackgroundWorker来定时刷新更新窗体主要是为了实现动画内容(GIFFlash等)的显示

至于移动的时候使用SetWindowPos主要是为了保证窗体一直位于顶层否则的话一些置顶的窗口(如QQ)等将覆盖当前窗口

已知问题

不支持视频截取

部分ToolTip提示无法显示

可能会造成背景窗口部分显示失效

SKHook类中对于键盘事件处理存在不足

还有一个问题就是当鼠标移动比较快的时候窗口边框会有残影不知道是什么原因这个问题在以往的Fram窗体中一直是困扰我的问题至今没有找到解决的办法

               

上一篇:.net 2.0(c#)下简单的FTP应用程序

下一篇:浅析VisualBasic.NET中的资源使用