成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

看看C# Hook 如何實(shí)現(xiàn)

開(kāi)發(fā) 后端
本文介紹了如何在程序中成功使用C#添加了Hook,供大家參考。

目前的程序中想要添加Hook,截獲鍵盤(pán)按鍵消息,所以上網(wǎng)找了一下關(guān)于C# Hook的東西。發(fā)現(xiàn)很多人都在說(shuō)在添加C# Hook不成功和不穩(wěn)定,而建議使用C++封一個(gè)Dll給C#使用。可喜的是最后我還是成功的在程序中使用C#添加了Hook,經(jīng)過(guò)測(cè)試還是沒(méi)有什么問(wèn)題的。

進(jìn)行Hook需要使用三個(gè)API函數(shù)

SetWindowsHookEx 進(jìn)行Hook的注冊(cè)

UnhookWindowsHookEx 取消已經(jīng)注冊(cè)的Hook

CallNextHookEx 將消息傳遞給下一個(gè)Hook函數(shù)

看一下定義

  1. [DllImport("user32.dll")]  
  2. private static extern IntPtr SetWindowsHookEx(  
  3.     HookType code, HookProc func, IntPtr instance, int threadID);  
  4.  
  5. [DllImport("user32.dll")]  
  6. private static extern int UnhookWindowsHookEx(IntPtr hook);  
  7.  
  8. [DllImport("user32.dll")]  
  9. private static extern int CallNextHookEx(  
  10.     IntPtr hook, int code, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam); 

我們需要定義一個(gè)delegate來(lái)接收消息

  1. private delegate int HookProc(int code, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam); 

定義兩個(gè)event提供給外界使用

  1. public delegate void HookEventHandler(object sender, HookEventArgs e);  
  2. public event HookEventHandler KeyDown;  
  3. public event HookEventHandler KeyUp; 

因?yàn)橐邮盏氖擎I盤(pán)的消息所以要定義一些消息,和我們要接收的結(jié)構(gòu)。 

  1. public class HookEventArgs : EventArgs  
  2.  {  
  3.      // using Windows.Forms.Keys instead of Input.Key since the Forms.Keys maps  
  4.      // to the Win32 KBDLLHOOKSTRUCT virtual key member, where Input.Key does not  
  5.      public Keys Key;  
  6.      public bool Alt;  
  7.      public bool Control;  
  8.      public bool Shift;  
  9.  
  10.      public HookEventArgs(UInt32 keyCode)  
  11.      {  
  12.          // detect what modifier keys are pressed, using   
  13.          // Windows.Forms.Control.ModifierKeys instead of Keyboard.Modifiers  
  14.          // since Keyboard.Modifiers does not correctly get the state of the   
  15.          // modifier keys when the application does not have focus  
  16.          this.Key = (Keys)keyCode;  
  17.          this.Alt = (System.Windows.Forms.Control.ModifierKeys & Keys.Alt) != 0;  
  18.          this.Control = (System.Windows.Forms.Control.ModifierKeys & Keys.Control) != 0;  
  19.          this.Shift = (System.Windows.Forms.Control.ModifierKeys & Keys.Shift) != 0;  
  20.      }  
  21.  }  
  22.  
  23.      private enum HookType : int 
  24.     {  
  25.         WH_JOURNALRECORD = 0,  
  26.         WH_JOURNALPLAYBACK = 1,  
  27.         WH_KEYBOARD = 2,  
  28.         WH_GETMESSAGE = 3,  
  29.         WH_CALLWNDPROC = 4,  
  30.         WH_CBT = 5,  
  31.         WH_SYSMSGFILTER = 6,  
  32.          WH_MOUSE = 7,  
  33.          WH_HARDWARE = 8,  
  34.          WH_DEBUG = 9,  
  35.          WH_SHELL = 10,  
  36.          WH_FOREGROUNDIDLE = 11,  
  37.          WH_CALLWNDPROCRET = 12,  
  38.          WH_KEYBOARD_LL = 13,  
  39.          WH_MOUSE_LL = 14  
  40.      }  
  41.  
  42.      public struct KBDLLHOOKSTRUCT  
  43.      {  
  44.          public UInt32 vkCode;  
  45.          public UInt32 scanCode;  
  46.          public UInt32 flags;  
  47.          public UInt32 time;  
  48.          public IntPtr extraInfo;  
  49.      } 

關(guān)鍵的在這里注冊(cè)C# Hook 

  1. private void Install()  
  2.  {  
  3.      if (_hookHandle != IntPtr.Zero)  
  4.          return;  
  5.            
  6.      Module[] list = System.Reflection.Assembly.GetExecutingAssembly().GetModules();  
  7.      System.Diagnostics.Debug.Assert(list != null && list.Length > 0);  
  8.  
  9.     _hookHandle = SetWindowsHookEx(_hookType,   
  10.          _hookFunction, Marshal.GetHINSTANCE(list[0]), 0);  
  11.  
  12.  } 

哦,還有HookType _hookType = HookType.WH_KEYBOARD_LL; 因?yàn)橐孬@鍵盤(pán)消息

還有_hookFunction = new HookProc(HookCallback);

其實(shí)最關(guān)鍵的是Marshal.GetHINSTANCE(list[0])得到當(dāng)前程序的instance,這樣這個(gè)C# Hook就是全局的C# Hook,這個(gè)位置也可以是null,這樣就不是全局C# Hook。

有個(gè)很奇怪的現(xiàn)象就是這個(gè)函數(shù),在調(diào)試狀態(tài)執(zhí)行不能成功,而做成Release以后運(yùn)行成功,所以你在做程序時(shí),不要因?yàn)檎{(diào)試失敗而對(duì)這個(gè)函數(shù)有懷疑,編一個(gè)Release版本的程序,獨(dú)立運(yùn)行再試一下。我使用的環(huán)境是VS2005 + Vista。

接收消息的函數(shù) 

  1. private int HookCallback(int code, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)  
  2.  {  
  3.      if (code <  0)  
  4.          return CallNextHookEx(_hookHandle, code, wParam, ref lParam);  
  5.  
  6.      if ((lParam.flags & 0x80) != 0 && this.KeyUp != null)  
  7.          this.KeyUp(thisnew HookEventArgs(lParam.vkCode));  
  8.  
  9.      if ((lParam.flags & 0x80) == 0 && this.KeyDown != null)  
  10.      {  
  11.          this.KeyDown(thisnew HookEventArgs(lParam.vkCode));  
  12.          if (lParam.vkCode == 44)  
  13.          {  
  14.              return 1;  
  15.          }  
  16.      }  
  17.  
  18.      return CallNextHookEx(_hookHandle, code, wParam, ref lParam);  
  19.  } 

這里會(huì)區(qū)分KeyUp和KeyDown,注意一定要調(diào)用CallNextHookEx,這樣會(huì)將這個(gè)消息在系統(tǒng)中繼續(xù)傳遞,這很重要。除非你想阻止這個(gè)消息,也不希望其他程序再處理這個(gè)消息。

下面最后的操作,釋放注冊(cè)。

  1. private void Uninstall()  
  2. {  
  3.     if (_hookHandle != IntPtr.Zero)  
  4.     {  
  5.         UnhookWindowsHookEx(_hookHandle);  
  6.         _hookHandle = IntPtr.Zero;  
  7.     }  

Ok,完成了。

【編輯推薦】

  1. C#發(fā)送Email郵件的方法解析
  2. 解析C#中is和as操作符的用法
  3. C# Excel COM組件的使用
  4. 如何判斷C#字符串是全角還是半角
  5. C#語(yǔ)言規(guī)范之小結(jié)
責(zé)任編輯:book05 來(lái)源: hi.baidu
相關(guān)推薦

2009-08-31 09:21:38

JavaScript調(diào)

2009-08-19 14:29:33

C#代理

2009-09-10 17:48:05

C# button

2009-06-16 10:20:05

多繼承C#

2009-09-01 18:06:06

c#保存窗體狀態(tài)

2009-03-12 13:49:30

DataTemplatWPFC#

2009-08-19 17:10:09

C#回調(diào)函數(shù)

2009-09-08 22:53:39

c# textbox數(shù)

2009-09-10 12:00:09

C# listbox

2009-08-19 17:00:07

C#實(shí)現(xiàn)PrintPa

2009-08-20 14:22:17

C#實(shí)現(xiàn) Contro

2009-08-25 17:55:52

C#實(shí)現(xiàn)Strateg

2009-08-31 15:55:17

C#實(shí)現(xiàn)Strateg

2009-08-21 16:32:41

C#空格表示

2009-09-01 18:29:10

C#繼承C#多態(tài)

2009-08-26 09:54:45

C#打印預(yù)覽C#打印

2024-09-26 00:00:00

Thread間傳值C#

2009-08-24 10:06:31

C#接口成員

2009-08-03 16:35:30

C#日期比較

2009-08-24 10:47:45

C#接口重實(shí)現(xiàn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲一区在线播放 | www312aⅴ欧美在线看 | 精品在线一区 | 日韩精品一区二区三区久久 | 亚洲精品性视频 | 亚洲精品视频网站在线观看 | 韩国av网站在线观看 | 亚洲国产精品99久久久久久久久 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 亚洲成av| av免费观看在线 | 美女在线观看国产 | 中文字幕国产在线 | 一级日批片 | 久草免费电影 | 国产精品久久精品 | 亚洲高清视频在线观看 | 午夜99| 九色在线观看 | 欧美全黄 | 日本一区二区三区免费观看 | 国产在线一区二区 | 日本不卡高字幕在线2019 | 在线观看国产 | 第四色狠狠 | 久久精品小短片 | www.99精品 | 一二三四av | 日韩成人免费视频 | 欧美日高清视频 | 亚洲福利片 | 日产精品久久久一区二区福利 | 久久99深爱久久99精品 | 福利网站导航 | 玖玖视频网 | 亚洲女人天堂成人av在线 | 国产精品久久久久久久久久免费看 | 色999日韩 | 99re国产精品 | 天天爱av | 欧美黄色绿像 |