最新想研究一下HOOK,上网查了几天的资料,想HOOK笔记本,发现我不能够指定只作用在笔记本里,就是说我在任何窗口按按键,都有反应,而且,反应速度非常慢,按了一个按键之后,要等几秒才有反应,于是代码如下:两个button,button1是启动按钮,button2是停止按钮,一个toolstatuslabel,用来显示状态,谢谢大家解答!!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace 笔记本hook
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
    private static extern IntPtr GetModuleHandle(string lpModuleName); 
        public Form1()
        {
            InitializeComponent();
        }
      static int hHook = 0;        const int WH_KEYBOARD = 13;        //声明键盘钩子的封送结构类型
        [StructLayout(LayoutKind.Sequential)]
        public class KeyboardHookStruct
        {
            public int vkCode; //表示一个在1到254间的虚似键盘码
            public int scanCode; //表示硬件扫描码
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        public void HOOK_Start()
        {
            if (hHook == 0)
            {
                NativeMethods.HookProc hp = new NativeMethods.HookProc(KbHookProc);
                hHook = NativeMethods.SetWindowsHookEx(13,
                    hp,
                    GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),
                    NativeMethods.FindWindow(null, "RawSocket类-记事本").ToInt32());                if (hHook == 0)
                {
                    MessageBox.Show("启动HOOK失败!");
                    toolStripStatusLabel1.Text = "启动失败";
                    return;
                }
                else toolStripStatusLabel1.Text = "启动成功";
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            HOOK_Start();
        }
        void UnHook()
        {
            if (hHook > 0)
            {
                bool ret = NativeMethods.UnhookWindowsHookEx(hHook);                if (ret == false)
                {
                    MessageBox.Show("停止HOOK失败!");
                    return;
                }                hHook = 0;
               toolStripStatusLabel1.Text="已经停止HOOK";
            }
        }        public static int KbHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode < 0)
            {
                return NativeMethods.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
            else
            {
                int r =  NativeMethods.CallNextHookEx(hHook, nCode, wParam, lParam);                if (wParam == (IntPtr)257)
                {
                }
                else
                {
                    KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));                    MessageBox.Show(MyKeyboardHookStruct.vkCode.ToString());
                }return r;
            }
        }
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnHook();
        }
internal static class NativeMethods
    {
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam); 
        }private void button2_Click(object sender, EventArgs e)
{
    UnHook();
}
    }
}
看到这里肯定辛苦大家了,无论解答与否,先谢谢了!C#HOOK

解决方案 »

  1.   

    不明白干嘛用的,没明白你的hook作用
      

  2.   

    就是我想在记事本里按键,然后记录我所按的按键(姑且说是记录吧,因为我只能够做到显示我所按的按键,利用Message.show()),谢谢
      

  3.   

    网上hook一堆,看你会不会用google
      

  4.   

    不要用message.show。或者说不能用弹窗体的方式显示。你试试把每个输入的字符都写到一个文件里面去,应该就正常了。
      

  5.   

    1.清楚SetWindowsHookEx的四个参数
      第一个:钩子类型(有的钩子类型只能是全局的)
      第二个:钩子回调方法
      第三个:回调方法所在模块handle
      第四个:与钩子关联的线程id2.WH_KEYBOARD = 13;   //这个13只能安装全局钩子,也就是说它能截获整个系统发的键盘消息
      

  6.   

    谢谢你们的回答,但是怎样做到只对笔记本安装钩子呢?网上查到资料说WH_KEYBOARD=2是注入式的,WH_KEYBOARD_LL=13 是全局的,再根据卷福哥的回答,我猜测可能是SetWindowsHookEx的第一个参数错了,
    但是当我这样,如代码所示
    hHook = SetWindowsHookEx(2,
                        hp,
                        GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),
                        0);
    的时候,hHOOK的值是没有变化过的,如果一开始hHook的值为0,它通过hHook = SetWindowsHookEx(省略)后也是0,搞不明白!
      

  7.   

    局部钩子  可以获取自己进程中的消息  类似.net中的NativeWindow的作用
    全局钩子  可以获取其它进程中的消息  你要获取记事本的键盘事件  那就用全局钩子好了
    请使用 WH_KEYBOARD_LL = 13;
    最后一个参数 指定记事本所在线程 若为0  表示拦截系统所有的键盘消息
      

  8.   

      1,2,3 参数全部错了,GetModuleHandle获取某一文件的模块句柄,这里用不上。C#钩子分为全局钩子和线程钩子。此处应该是线程钩子。所以1参数应该为2,第二个参数为回调应该在独立模块句柄里面,第三个参数为回调函数独立模块句柄标记。
       参考:http://download.csdn.net/detail/tangyanzhi1111/5647827
      

  9.   

    请把“MessageBox.Show(MyKeyboardHookStruct.vkCode.ToString());”去掉,换成其他展示方式,例如TextBox1.Text=MyKeyboardHookStruct.vkCode.ToString();反应速度肯定不会慢了,你的这个问题我也遇到过的
      

  10.   

    谢谢9楼的建议,我下了你连接上的东西,但是看不明白,还是谢谢了!第二个参数应该没有错吧,我查了一下资料,根据您们的回答再结合资料我将函数改成如下:IntPtr Hwnd=FindWindow(null,"无标题 - 记事本");
    int OutId;
    hHook = SetWindowsHookEx(2,
                        hp,
                        IntPtr.Zero,
                        GetWindowThreadProcessId(Hwnd,out OutId);发现hHook的值为0;就是说设置钩子失败了。求救!最好有代码,谢谢