`

C#系统钩子的实现

    博客分类:
  • C#
阅读更多

这几天用C#做了一个抓图软件,其中用到了系统钩子技术。

在这里发表下自己用C#实现系统钩子的心得,希望对我的朋友们有所帮助。


看了很多资料,都提到系统钩子(Hook)必须是一个dll,这样Windows才能在所有进程中共享钩子代码。

与钩子相关的3个Windows API函数是:
SetWindowsHookEx、UnhookWindowsHookEx、CallNextHookEx,它们的简要说明如下:
HHOOK SetWindowsHookEx(
    int       idHook,
    HOOKPROC  lpfn,
    HINSTANCE hMod,
    DWORD     dwThreadId
);

idHook — 系统钩子类型,实际上是一个int值,具体的定义请看MSDN
lpfn — 钩子回调函数指针,当收到钩子消息时就执行这个回调函数,回调函数有3个参数,不同类型的钩子这3个参数有不同的含义,具体请看MSDN。
hMod — DLL实例句柄(我猜是这样,我不熟悉Win32API编程),当钩子为系统钩子时这个参数是必须的,如果是单个程序或者线程使用的钩子那么可以不用这个值。
dwThreadId — 线程ID,如果是单个程序或者线程使用的钩子这个参数是必须的。

SetWindowsHookEx返回所设置的钩子的句柄。
BOOL UnhookWindowsHookEx(HHOOK hhk);

hhk — 所要注销的钩子的句柄

UnhookWindowsHookEx返回注销钩子是否成功。
LRESULT CallNextHookEx(
    HHOOK  hhk,
    int    nCode,
    WPARAM wParam,
    LPARAM lParam
);

hhk — 起始钩子句柄,如果是在钩子回调函数中调用CallNextHookEx时传的通常是本钩子句柄。
nCode — 钩子回调函数参数1,具体含义视钩子类型而定。
wParam — 钩子回调函数参数2,具体含义视钩子类型而定。
lParam — 钩子回调函数参数3,具体含义视钩子类型而定。

重点重复说明下CallNextHookEx函数,这个函数的功能是在执行完系统钩子的回调函数后接着调用下一个钩子函数,当设置的钩子是底层键盘或者鼠标钩子时如果不这么做将会时键盘和鼠标”失灵”。

从以上3个函数的简要说明可以看出所用到的参数几乎都是简单的参数,稍微复杂就是回调函数(在C#中用delegate类型来实现,后面会提到),但是最让人头疼的就是DLL的实例句柄,C#制作的DLL并不像C做的DLL有DllMain入口可以接受到DLL实例句柄。

我目前唯一的办法就是使用C做一个系统钩子DLL再让C#调用。底下是DLL的代码。
#define  _WIN32_WINNT 0x0500

#include <Windows.h>
#include <WinUser.h>

#define Dll_Export __declspec(dllexport) 

/* DLL实例句柄 */ 
HINSTANCE instance = NULL;

BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    instance  =  hInstance;
    return  TRUE;

/* 
* 功能:设置系统钩子
* hookType -- 钩子类型
* hookproc -- 钩子回调函数
*/
Dll_Export HHOOK SetHook(int hookType, HOOKPROC hookproc)
{
    return SetWindowsHookEx(hookType, hookproc, instance, NULL);
}

/* 
* 功能:注销钩子
* hook -- 钩子句柄
*/ 
Dll_Export BOOL UnHook(HHOOK hook)
{
    if (hook != NULL)
        return UnhookWindowsHookEx(hook);
    else 
        return 0;
}

然后在C#项目中创建一个系统钩子类,提供创建钩子和注销钩子的接口,代码如下:
public class Hook
{
    [DllImport("LowLevelHook.dll")]
    public extern static IntPtr SetHook(int hookType, HookProc hookProc);

    [DllImport("LowLevelHook.dll")]
    public extern staticbool UnHook(IntPtr hook);
}

上面用到的User32.HookProc类型不是.NET框架提供的,是自己定义的一个委托类型,声明如下:
public delegate int HookProc( int  nCode, IntPtr wParam, IntPtr lParam);

现在你的C#程序就可以使用各种系统钩子了,我们目前已经使用的有低级别鼠标钩子和低级别键盘钩子。

应用低级别鼠标钩子时会遇到这样一个问题:

低级别鼠标钩子的回调函数lParam是一个MSLLHOOKSTRUCT结构体指针,C#中怎么获取这个结构体的实例呢?实现代码如下
MSLLHOOKSTRUCT _mstr;

unsafe
{
    _mstr =* (User32.MSLLHOOKSTRUCT *)lParam.ToPointer();
}

通过声明非安全代码来获取指针所指对象。

MSLLHOOKSTRUCT结构体的C#定义如下:
[StructLayout(LayoutKind.Sequential)]
public struct MSLLHOOKSTRUCT
{
    public Point Point;

    public int MouseData;
    public int Flags;
    public int Time;
    public int ExtraInfo;
}

HookType枚举值,这些值可以在Win32 API的相关头文件中找到,有LL字样的就是低级钩子:
public enum HookTypes : int
{
        WH_JOURNALRECORD    = 0,
        WH_JOURNALPLAYBACK  = 1,
        WH_KEYBOARD         = 2,
        WH_GETMESSAGE       = 3,
        WH_CALLWNDPROC      = 4,
        WH_CBT              = 5,
        WH_SYSMSGFILTER     = 6,
        WH_MOUSE            = 7,
        WH_HARDWARE         = 8,
        WH_DEBUG            = 9,
        WH_SHELL            = 10,
        WH_FOREGROUNDIDLE   = 11,
        WH_CALLWNDPROCRET   = 12,
        WH_KEYBOARD_LL      = 13,
        WH_MOUSE_LL         = 14
}

做个试验程序,这个程序功能是获取鼠标全局坐标和锁定鼠标一定时间。

分享到:
评论

相关推荐

    c#系统钩子(c#源码)

    在IT领域,尤其是Windows编程中,...总的来说,C#系统钩子是Windows编程中一项强大的技术,它可以帮助我们实现许多高级功能。通过学习和实践,开发者可以更深入地理解和掌握Windows编程的本质,提升自己的技能水平。

    C# 采用钩子实现扫码枪功能.zip

    在这里,"C# 采用钩子实现扫码枪功能"意味着开发者通过设置钩子来监听USB扫码枪的输入,当扫码枪扫描到条形码时,钩子会捕获这一事件并处理输入的数据。 实现这个功能的过程可能包括以下步骤: 1. **注册钩子**: ...

    C#写的系统钩子

    本项目是用C#语言编写的一个系统钩子的实现,它已经封装成了一个方便使用的类库。 C#语言虽然原生不支持系统钩子的概念,但它可以通过P/Invoke技术调用Windows API来实现。P/Invoke允许.NET Framework中的C#代码...

    C#键盘钩子实现全局快捷键.pdf

    标题中提到的"C#键盘钩子实现全局快捷键",是指在C#编程中利用Windows钩子(Hook)机制来捕获和处理键盘事件,以此创建可以在系统范围内工作的快捷键。这种技术涉及到深入的系统底层交互,通常使用Win32 API来实现。...

    C# 鼠标钩子 监测鼠标双击事件

    在C#编程中,鼠标钩子(Mouse Hook)是一种用于监听和处理系统鼠标事件的技术。通过设置全局鼠标钩子,开发者可以捕获到系统中所有窗口的鼠标活动,包括单击、双击、移动等事件。这个项目"鼠标钩子 监测鼠标双击事件...

    C# 键盘钩子实例源码

    【C# 键盘钩子实例源码】是关于C#编程语言中实现键盘事件监听的一个实例项目。在这个实例中,开发者使用了Windows API(应用程序接口)中的键盘钩子技术来捕获系统级别的键盘输入事件。键盘钩子是一种机制,允许程序...

    C#中通过钩子实现屏蔽组合功能键

    C#中也可以通过调用Win32 API安装和卸载钩子函数,实现基于钩子的特定功能。 本实例为通过C#屏蔽键盘、利用HOOK钩子屏蔽ctrl+alt+delete组合键的示例源码,可直接编译。 示例支持屏蔽按键、解除屏蔽。

    C#使用全局钩子(hook)

    在 C#这种 managed 环境下,如果想实现全局钩子就必须使用 low-level 的 hook。 四、WH_KEYBORAD_LL 和 WH_MOUSE_LL 钩子的使用 WH_KEYBORAD_LL 和 WH_MOUSE_LL 钩子是低级别的钩子,它们可以捕捉到键盘和鼠标的...

    C#全局钩子屏蔽键盘按键Demo

    综上所述,"C#全局钩子屏蔽键盘按键Demo"是一个实用的示例,展示了如何利用C#和Windows API实现全局键盘监控与屏蔽功能,对于学习Windows编程和系统级交互具有一定的参考价值。但使用此类技术时应谨慎,确保符合合法...

    c#全局钩子现实

    在C#中实现全局钩子,可以让我们编写的应用程序捕获并处理整个系统级别的消息。这篇教程将带你深入了解如何在C#中设置和使用全局钩子。 首先,我们要理解什么是钩子。钩子是Windows操作系统提供的一种机制,允许...

    纯C#钩子实现及应用

    【标题】"纯C#钩子实现及应用"揭示了如何使用C#编程语言来创建和应用钩子技术。在Windows操作系统中,钩子是一种机制,允许程序拦截和处理特定类型的系统事件,如键盘输入、鼠标点击等。通过设置钩子,开发者可以...

    c# 全局钩子 (实例)

    本篇内容将详细介绍如何使用C#实现全局键盘钩子,并提供一个具体的示例代码来演示其工作原理。 #### 核心概念 - **全局钩子**:一种Windows API提供的机制,用于捕获整个系统的事件。 - **低级别键盘钩子**:一种...

    C#鼠标钩子源码.zip

    3. **KeyboardHook.cs** 和 **全局键盘钩子.csproj**:尽管标题是关于键盘钩子,但这里可能包含了一些通用的钩子实现逻辑,可能有部分代码可以复用在鼠标钩子的实现中。 4. **MouseHook.cs**(未在列表中,但通常是...

    强大的C#钩子。全局钩子,获取输入值。键盘值已处理

    C#中的钩子实现机制 在C#中,钩子是通过调用Windows API函数`SetWindowsHookEx`来创建的。为了与这些API交互,我们需要使用`DllImport`属性来导入相关的DLL文件。在这个例子中,我们主要关注以下几点: - **`...

    C# winform键盘钩子示例

    在C# WinForm开发中,有时我们需要监听键盘输入或者实现特定快捷键的处理,这就需要用到键盘钩子(Keyboard Hook)。本文将深入解析如何在C# WinForm应用中创建和使用键盘钩子,以及如何实现多快捷键的动态注册。 ...

    C#键盘钩子实例源码

    标题中的"C#键盘钩子实例源码"是一个关于利用C#编程语言实现键盘钩子(Keyboard Hook)技术的示例项目。键盘钩子是Windows API提供的一种机制,允许应用程序监听...这是一个深入研究Windows API和C#系统编程的好例子。

    c++和c#键盘钩子

    本文将深入探讨如何在C++和C#这两种不同的编程语言中实现键盘钩子。 ### 一、C++键盘钩子 在C++中,我们可以利用Windows API中的`SetWindowsHookEx`函数来设置键盘钩子。这个函数允许我们在指定的线程或所有线程中...

    c# 全局钩子(使用c++编写的鼠标过程)

    总之,通过C++编写的DLL和C#的混合编程,我们可以实现一个c#全局鼠标钩子,监控和处理系统的鼠标事件。这个过程中涉及到了Windows API的使用、DLL的创建与调用、多语言混合编程以及对操作系统级别的理解。

    C#设置键盘钩子屏蔽键盘信息

    C#键盘钩子(Keyboard Hook)就是利用这一机制来实现键盘输入的拦截和屏蔽。下面将详细介绍C#实现键盘钩子的相关知识点。 首先,键盘钩子是一种特定类型的钩子,主要用于监听键盘事件,如按键按下和释放。当用户在...

Global site tag (gtag.js) - Google Analytics