欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于C#实现的HOOK键盘钩子实例代码

程序员文章站 2024-02-20 22:51:05
本文所述为基于c#实现的hook实例,该实例可用来屏蔽系统热键。程序主要实现了安装钩子、传递钩子、卸载钩子等功能。在传递钩子中:

本文所述为基于c#实现的hook实例,该实例可用来屏蔽系统热键。程序主要实现了安装钩子、传递钩子、卸载钩子等功能。在传递钩子中:
<param name="phookhandle">是您自己的钩子函数的句柄。用该句柄可以遍历钩子链</param>
<param name="ncode">把传入的参数简单传给callnexthookex即可</param>
<param name="wparam">把传入的参数简单传给callnexthookex即可</param>,
在hook类中定义了一些私有变量:键盘钩子句柄、键盘钩子委托实例、底层的钩子变量等。在钩子捕获消息后,对消息进行处理。

具体实现hook代码如下:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.windows.forms;
using system.runtime.interopservices;
using system.reflection;
using system.io;
namespace 设置和屏蔽系统热键
{
  class hook
  {
    #region 私有变量
 private intptr m_pkeyboardhook = intptr.zero;/// 键盘钩子句柄
 public delegate int hookproc(int ncode, int32 wparam, intptr lparam);/// 钩子委托声明
 private hookproc m_keyboardhookprocedure;/// 键盘钩子委托实例
  public const int idhook = 13;/// 底层的钩子变量
  [dllimport("user32.dll", callingconvention = callingconvention.stdcall)]
  public static extern intptr setwindowshookex(int idhook, hookproc lpfn, intptr pinstance, int threadid);/// 安装钩子
  [dllimport("user32.dll", callingconvention = callingconvention.stdcall)]/// 卸载钩子
  public static extern bool unhookwindowshookex(intptr phookhandle);
    /// 传递钩子
      /// <param name="phookhandle">是您自己的钩子函数的句柄。用该句柄可以遍历钩子链</param>
    /// <param name="ncode">把传入的参数简单传给callnexthookex即可</param>
    /// <param name="wparam">把传入的参数简单传给callnexthookex即可</param>
    /// <param name="lparam"></param>
    /// <returns></returns>
    [dllimport("user32.dll", callingconvention = callingconvention.stdcall)]
    public static extern int callnexthookex(intptr phookhandle, int ncode, int32 wparam, intptr lparam);
    [structlayout(layoutkind.sequential)]
    public struct keymsg
    {
      public int vkcode;
      public int scancode;
      public int flags;
      public int time;
      public int dwextrainfo;
    }
    protected const int wm_queryendsession = 0x0011;
    protected const int wm_keydown = 0x100;
    protected const int wm_keyup = 0x101;
    protected const int wm_syskeydown = 0x104;
    protected const int wm_syskeyup = 0x105;
    protected const byte vk_shift = 0x10;
    protected const byte vk_capital = 0x14;
    protected const byte vk_numlock = 0x90;
    protected const byte vk_lshift = 0xa0;
    protected const byte vk_rshift = 0xa1;
    protected const int vk_lwin = 91;
    protected const int vk_rwin = 92;
    protected const byte vk_lcontrol = 0xa2;
    protected const byte vk_rcontrol = 0x3;
    protected const byte vk_lalt = 0xa4;
    protected const byte vk_ralt = 0xa5;
    protected const byte llkhf_altdown = 0x20;
    public bool porwer = true;//是否屏蔽porwer键
    public static int pp = 0;//热键的返回值
    public static bool isset = false;//是否设置屏蔽热键,false为设置屏蔽的热键
    public static bool ishotkey = false;
    public static bool isinstall = false;//是否安装钩子,true为安装
    #endregion
    #region 事件的声明
    public event keyeventhandler keydown;//键盘按下事件
    public event keyeventhandler keyup;//键盘松开事件
    public event keypresseventhandler keypress;//键盘单击事件
    #endregion
    #region 方法
    /// <summary>
    /// 钩子捕获消息后,对消息进行处理
    /// </summary>
    /// <param ncode="int">标识,键盘是否操作</param> 
    /// <param wparam="int">键盘的操作值</param>
    /// <param lparam="intptr">指针</param>
    private int keyboardhookproc(int ncode, int wparam, intptr lparam)
    {
      if (ncode > -1 && (keydown != null || keyup != null || keypress != null))
      {
        keymsg keyboardhookstruct = (keymsg)marshal.ptrtostructure(lparam, typeof(keymsg));//获取钩子的相关信息
        keyeventargs e = new keyeventargs((keys)(keyboardhookstruct.vkcode));//获取keyeventargs事件的相磁信息
        switch (wparam)
        {
          case wm_keydown://键盘按下操作
          case wm_syskeydown:
            if (keydown != null)//如果加载了当前事件
            {
              keydown(this, e);//调用该事件
            }
            break;
          case wm_keyup://键盘松开操作
          case wm_syskeyup:
            if (keyup != null)//如果加载了当前事件
            {
              keyup(this, e);//调用该事件
            }
            break;
        }
      }
      return pp;//是否屏蔽当前热键,1为屏蔽,2为执行
    }
    #endregion
    #region 安装、卸载钩子
    /// <summary>
    /// 安装钩子
    /// </summary>
    /// <returns>是否安装成功</returns>
    public bool start()
    {
      intptr pinstance = (intptr)4194304;//钩子所在实例的句柄
      if (this.m_pkeyboardhook == intptr.zero)//如果键盘的句柄为空
      {
        this.m_keyboardhookprocedure = new hookproc(keyboardhookproc);//声明一个托管钩子
        this.m_pkeyboardhook = setwindowshookex(idhook, m_keyboardhookprocedure, pinstance, 0);//安装钩子
        if (this.m_pkeyboardhook == intptr.zero)//如果安装失败
        {
          this.stop();//卸载钩子
          return false;
        }
      }
      isinstall = true;//安装了钩子
      return true;
    }
    /// <summary>
    /// 卸载钩子
    /// </summary>
    /// <returns>是否卸载成功</returns>
    public bool stop()
    {
      if (isinstall == false)//如果没有安装钩子
      {
        return true;
      }
      bool result = true;
      if (this.m_pkeyboardhook != intptr.zero)//如果安装了钩子
      {
        result = (unhookwindowshookex(this.m_pkeyboardhook) && result);//卸载钩子
        this.m_pkeyboardhook = intptr.zero;//清空键盘的钩子句柄
      }
      return result;
    }
    #endregion 公共方法
  }
}