您的位置:首页 > 编程语言 > C#

C#钩子实现简单鼠标键盘的监控和屏蔽

2008-01-14 15:40 781 查看
   
概要

1 目的:完成简单的监控和屏蔽

2 技术:钩子(系统监控必须全局钩子)

3 步骤:

A 安装钩子

B 回调函数

C 处理函数

D 普通业务处理

……

4 完成

下载源程序和运行程序
http://files.cnblogs.com/hocylan/KeyboardHook.rar
运行界面如下:



说明:

在C++中实现该功能十分简单,也有很多经典例子可以实现,在C#中确有很多问题会出现。

对于钩子知识不太熟悉可以参考我转载的另一篇文章:http://www.cnblogs.com/hocylan/articles/1033895.html[微软HOOK技术专题]

大概步骤



其实主要就是调用windows API

第一步:安装钩子:SetWindowsHookEx(WH_Codes idHook, HookProc lpfn,IntPtr pInstance, int threadId);

第二步:回调和处理 CallNextHookEx(IntPtr pHookHandle, int nCode,Int32 wParam, IntPtr lParam);

第三步:完成普通的业务处理其它流程

将封装的钩子应用到系统中…….

private void start_Click(object sender, EventArgs e)

{ hook_Main.InstallHook("1");}

private void stop_Click(object sender, EventArgs e)

{this.hook_Main.UnInstallHook();}

private void stopkeyboard_Click(object sender, EventArgs e)

{ hook_Main.InstallHook("2"); }

第四步:拆卸钩子UnhookWindowsHookEx(IntPtr pHookHandle);

四 重要代码和解释:

*封装的hook类:

using System;

using System.Windows.Forms;

using System.Runtime.InteropServices; //必须引用

using System.Reflection; //必须引用

namespace KeyboardHook

{

class Hocy_Hook

{

#region私有常量

///<summary>

///按键状态数组

///</summary>

private readonly byte[] m_KeyState = new byte[ 256 ];

private string flags;

//flag=0 正常 flag=1 监控状态 flag=2 屏蔽键盘//

#endregion私有常量

#region私有变量

///<summary>

///鼠标钩子句柄

///</summary>

private IntPtr m_pMouseHook = IntPtr.Zero;

///<summary>

///键盘钩子句柄

///</summary>

private IntPtr m_pKeyboardHook = IntPtr.Zero;

///<summary>

///鼠标钩子委托实例

///</summary>

///<remarks>

///不要试图省略此变量,否则将会导致

///激活CallbackOnCollectedDelegate 托管调试助手(MDA)。

///详细请参见MSDN中关于CallbackOnCollectedDelegate 的描述

///</remarks>

private HookProc m_MouseHookProcedure;

///<summary>

///键盘钩子委托实例

///</summary>

///<remarks>

///不要试图省略此变量,否则将会导致

///激活CallbackOnCollectedDelegate 托管调试助手(MDA)。

///详细请参见MSDN中关于CallbackOnCollectedDelegate 的描述

///</remarks>

private HookProc m_KeyboardHookProcedure;

// 添加

public event MouseEventHandler OnMouseActivity;

private const byte VK_SHIFT = 0x10 ;

private const byte VK_CAPITAL = 0x14;

private const byte VK_NUMLOCK = 0x90;

#endregion私有变量

#region事件定义

///<summary>

///鼠标更新事件

///</summary>

///<remarks>当鼠标移动或者滚轮滚动时触发</remarks>

public event MouseUpdateEventHandler OnMouseUpdate;

///<summary>

///按键按下事件

///</summary>

public event KeyEventHandler OnKeyDown;

///<summary>

///按键按下并释放事件

///</summary>

public event KeyPressEventHandler OnKeyPress;

///<summary>

///按键释放事件

///</summary>

public event KeyEventHandler OnKeyUp;

#endregion事件定义

#region私有方法

///<summary>

///鼠标钩子处理函数

///</summary>

///<param name="nCode"></param>

///<param name="wParam"></param>

///<param name="lParam"></param>

///<returns>鼠标钩子处理函数</returns>

private int MouseHookProc( int nCode, Int32 wParam, IntPtr lParam )

{

if ((nCode >= 0) && (OnMouseActivity != null))

{

//Marshall the data from callback.

MouseHookStruct mouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

//detect button clicked

MouseButtons button = MouseButtons.None;

short mouseDelta = 0;

switch (wParam)

{

case (int)WM_MOUSE.WM_LBUTTONDOWN:

//case WM_LBUTTONUP:

//case WM_LBUTTONDBLCLK:

button = MouseButtons.Left;

break;

case (int)WM_MOUSE.WM_RBUTTONDOWN:

//case WM_RBUTTONUP:

//case WM_RBUTTONDBLCLK:

button = MouseButtons.Right;

break;

case (int)WM_MOUSE.WM_MOUSEWHEEL:

//If the message is WM_MOUSEWHEEL, the high-order word of mouseData member is the wheel delta.

//One wheel click is defined as WHEEL_DELTA, which is 120.

//(value >> 16) & 0xffff; retrieves the high-order word from the given 32-bit value

mouseDelta = (short)((mouseHookStruct.MouseData>> 16) & 0xffff);

//TODO: X BUTTONS (I havent them so was unable to test)

//If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP,

//or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released,

//and the low-order word is reserved. This value can be one or more of the following values.

//Otherwise, mouseData is not used.

break;

}

//double clicks

int clickCount = 0;

if (button != MouseButtons.None)

if (wParam == (int)WM_MOUSE.WM_LBUTTONDBLCLK || wParam == (int)WM_MOUSE.WM_RBUTTONDBLCLK) clickCount = 2;

else clickCount = 1;

//generate event

MouseEventArgs e = new MouseEventArgs(

button,

clickCount,

mouseHookStruct.Point.X,

mouseHookStruct.Point.Y,

mouseDelta);

//raise it

OnMouseActivity(this, e);

}

//*

return Win32API.CallNextHookEx( this.m_pMouseHook, nCode, wParam, lParam );

}

///<summary>

///键盘钩子处理函数

///</summary>

///<param name="nCode"></param>

///<param name="wParam"></param>

///<param name="lParam"></param>

///<returns></returns>

///<remarks></remarks>

private int KeyboardHookProc( int nCode, Int32 wParam, IntPtr lParam )

{

switch (flags)

{

case "2":

return 1;

break;

case "1":

break;

}

bool handled = false;

//it was ok and someone listens to events

if ((nCode >= 0) && (this.OnKeyDown != null || this.OnKeyUp!= null || this.OnKeyPress!= null))

{

//read structure KeyboardHookStruct at lParam

KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

//raise KeyDown

if (this.OnKeyDown != null && (wParam == (int)WM_KEYBOARD.WM_KEYDOWN || wParam == (int)WM_KEYBOARD.WM_SYSKEYDOWN))

{

Keys keyData = (Keys)MyKeyboardHookStruct.VKCode;

KeyEventArgs e = new KeyEventArgs(keyData);

this.OnKeyDown(this, e);

handled = handled || e.Handled;

}

// raise KeyPress

if (this.OnKeyPress != null && wParam == (int)WM_KEYBOARD.WM_KEYDOWN)

{

bool isDownShift, isDownCapslock;

try

{

isDownShift = ((Win32API.GetKeyStates(VK_SHIFT) & 0x80) == 0x80 ? true : false);

isDownCapslock = (Win32API.GetKeyStates(VK_CAPITAL) != 0 ? true : false);

}

catch

{

isDownCapslock = false;

isDownShift= false;

}

byte[] keyState = new byte[256];

Win32API.GetKeyboardState(keyState);

byte[] inBuffer = new byte[2];

if (Win32API.ToAscii(MyKeyboardHookStruct.VKCode,

MyKeyboardHookStruct.ScanCode,

keyState,

inBuffer,

MyKeyboardHookStruct.Flags) == 1)

{

char key = (char)inBuffer[0];

if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);

KeyPressEventArgs e = new KeyPressEventArgs(key);

this.OnKeyPress(this, e);

handled = handled || e.Handled;

}

}

// raise KeyUp

if (this.OnKeyUp != null && (wParam == (int)WM_KEYBOARD.WM_KEYUP || wParam == (int)WM_KEYBOARD.WM_SYSKEYUP))

{

Keys keyData = (Keys)MyKeyboardHookStruct.VKCode;

KeyEventArgs e = new KeyEventArgs(keyData);

this.OnKeyUp(this, e);

handled = handled || e.Handled;

}

}

//if event handled in application do not handoff to other listeners

if (handled)

return 1;

else

return Win32API.CallNextHookEx(this.m_pKeyboardHook, nCode, wParam, lParam);

}

#endregion私有方法

#region公共方法

///<summary>

///安装钩子

///</summary>

///<returns></returns>

public bool InstallHook(string flagsinfo)

{

this.flags = flagsinfo;

IntPtr pInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().ManifestModule);

//pInstance = (IntPtr)4194304;

//注意:很多时候得到的pInstanc无法安装钩子,请检查值是否为4194304,在应用程序中可以直接取得pinstance的

// IntPtr pInstanc2 = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly());

// Assembly.GetExecutingAssembly().GetModules()[0]

//安装鼠标钩子

if ( this.m_pMouseHook == IntPtr.Zero )

{

this.m_MouseHookProcedure = new HookProc( this.MouseHookProc );

this.m_pMouseHook = Win32API.SetWindowsHookEx( WH_Codes.WH_MOUSE_LL,this.m_MouseHookProcedure, pInstance, 0 );

// WH_Codes.WH_MOUSE_LL为全局钩子即系统钩子,否则应该为WH_Codes.WH_KEYBOARD,即普通钩子

if ( this.m_pMouseHook == IntPtr.Zero )

{

this.UnInstallHook();

return false;

}

}

if ( this.m_pKeyboardHook == IntPtr.Zero ) //安装键盘钩子

{

this.m_KeyboardHookProcedure = new HookProc( this.KeyboardHookProc );

// WH_Codes.WH_KEYBOARD_LL为全局钩子即系统钩子,否则应该为WH_Codes.WH_KEYBOARD,即普通钩子

this.m_pKeyboardHook = Win32API.SetWindowsHookEx( WH_Codes.WH_KEYBOARD_LL,this.m_KeyboardHookProcedure, pInstance, 0 );

if ( this.m_pKeyboardHook == IntPtr.Zero )

{

this.UnInstallHook();

return false;

}

}

return true;

}

///<summary>

///卸载钩子

///</summary>

///<returns></returns>

public bool UnInstallHook()

{

bool result = true;

if ( this.m_pMouseHook != IntPtr.Zero )

{

result = ( Win32API.UnhookWindowsHookEx( this.m_pMouseHook ) && result );

this.m_pMouseHook = IntPtr.Zero;

}

if ( this.m_pKeyboardHook != IntPtr.Zero )

{

result = ( Win32API.UnhookWindowsHookEx( this.m_pKeyboardHook ) && result );

this.m_pKeyboardHook = IntPtr.Zero;

}

return result;

}

#endregion公共方法

#region构造函数

///<summary>

///钩子类

///</summary>

///<remarks>本类仅仅简单实现了WH_KEYBOARD_LL 以及WH_MOUSE_LL </remarks>

public Hocy_Hook()

{

Win32API.GetKeyboardState( this.m_KeyState );

}

#endregion构造函数

}

}

另外感谢来自Germany的George Mamaladze,看了他的代码,给了我比较好的思路

http://www.codeproject.com/KB/cs/globalhook.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: