当前位置: 移动技术网 > IT编程>开发语言>c# > 基于C#实现的HOOK键盘钩子实例代码

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

2019年07月18日  | 移动技术网IT编程  | 我要评论

本文所述为基于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 公共方法
  }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网