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

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

2008-12-31 10:16 776 查看
概要

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

{

public 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 构造函数

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: