(我指导的C#程序设计论文,已于《软件报》发表)
有关C#HOOK的功能,网上有许多相关的文章介绍,但都是纯理论方面的解释,具体实例不多。希望本文起到抛砖引玉的作用,对有心了解C#环境下HOOK编程的程序员有所帮助。
一、程序设计思想
为了能够监视到学生正在上网玩游戏,需要知道当前的IE窗口是否打开,并且知道学生的键盘输入情况。一般玩游戏都要频繁使用四个方向键和空格键,本程序将简单统计这五个键的使用频率,当在一定时间内按键频率达到设定标准时,即认为学生在玩游戏,关闭其IE窗口。因此我们需要解决三个问题:截获学生键盘的输入情况、获取系统当前正在运行的进程列表和停止IE进程。在本方案中,利用系统钩子中的WH_KEYBOARD_LLHook来截取键盘输入;利用GetProcesses()来获取进程;利用Kill()来停止进程。
二、编程实施方案
1 编程的重点是利用系统钩子中的WH_KEYBOARD_LLHook来截取键盘输入,我们将这部分功能单独在UserActivityHook.cs中编写,然后通过计时器控件进行定时调用,以便统计规定时间内键盘的输入情况。UserActivityHook.cs中的程序代码主要包括以下几部分。
public class UserActivityHook : object { public UserActivityHook() { |
public event KeyEventHandler KeyDown; public delegate int HookProc(int nCode, Int32wParam, IntPtr lParam); static int hKeyboardHook = 0; public const int WH_KEYBOARD_LL = 13;//13表示采用全局钩子监听键盘消息 HookProc KeyboardHookProcedure;//将KeyboardHookProcedure声明为HookProc类 //对键盘消息,简单定义为以下结构 [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct{ } [DllImport("user32")] public static extern int GetKeyboardState(byte[]pbKeyState); private const int WM_KEYDOWN = 0x100; private const int WM_SYSKEYDOWN = 0x104; |
public static extern int SetWindowsHookEx(intidHook, HookProc lpfn, IntPtr hInstance, int threadId); public static extern bool UnhookWindowsHookEx(intidHook); public static extern int CallNextHookEx(int idHook,int nCode, Int32 wParam, IntPtr lParam); |
④ Hook在使用之前,需要进行安装,具体代码如下:
public void Start(){ if(hKeyboardHook == 0) { Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0); } } |
public void Stop(){ |
private int KeyboardHookProc(int nCode, int wParam,IntPtr lParam){ if ((nCode >= 0)&& (KeyDown!=null )) { KeyboardHookStruct MyKeyboardHookStruct =(KeyboardHookStruct)Marshal.PtrToStructure(lParam,typeof(KeyboardHookStruct)); } return CallNextHookEx(hKeyboardHook, nCode, wParam,lParam); } |
① 在原有的using基础下添加以下using语句。
using System.Runtime.InteropServices; using System.Threading; using System.Globalization; using System.Diagnostics; |
② 定义初始化相关的变量、过程、数组。
private UserActivityHookhook;//定义键盘HOOK程序,具体代码见UserActivityHook.cs文件 private struct kk //定义一个结构,用于统计输入的键的次数 private kk[] keycount; |
③在Form1()中初始化keycount数组,用于存放五个常用游戏键的统计信息,可根据需要添加监控的键。如keycount[0].button = "Up";
④编写hook_KeyDown(),对截获的键进行判断,如果属于5个按键之一,则相应的击键次数加1,同时判断击键次数是否达到规定的数目,如果达到规定的数目,则调用stopprocess()关闭相应的进程。
⑤编写stopprocess()来获取系统中当前正在运行的进程,并检查是否打开了IE窗口,是,则关闭IE进程,这部分程序可以根据需要修改,以关闭其他进程。主要代码是:
private void stopprocess(){ |
int iProcID = procList[i].Id; procList[i].ProcessName == "iexplore") |
⑥ 最后,我们将对计时器控件timer1的tick事件进行编程,以便每隔一定的时间自动调用UserActivityHook,截获键盘输入的键并对截获的键进行统计。
private void timer1_Tick(object sender, EventArgse) { } |
联系客服