如何正确解钩

本文关键字:何正确 | 更新日期: 2023-09-27 18:16:56

我做了一个非常简单的Hook代码(我是初学者)。

我打开记事本测试。

如果我按任意键,它会发出哔哔声并打印出来。

除"x"键外,为终止键。

问题:

我不想看到"x"键被打印出来。我刚退出这个项目。我该怎么做?

namespace HookingStudy
{
    class HookingClass          
    {
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = hookCallBack;
        private static IntPtr _hookID = IntPtr.Zero;                    
        public static void Main()
        {
            Beep(1111, 222);
            _hookID = SetHook(_proc);
            Application.Run();
        }
        private static IntPtr hookCallBack(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if( nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN )
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if( vkCode.ToString() == "88" )                 //   88 ("x" key)
                {
                    Beep(7777, 222);
                    UnhookWindowsHookEx(_hookID);     
                    Process.GetCurrentProcess().Kill(); 
                }
                Beep(2222, 55);
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);  
        }
        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using( Process curProcess = Process.GetCurrentProcess() )
            using( ProcessModule curModule = curProcess.MainModule )
            {
                return SetWindowsHookEx(13, proc, GetModuleHandle(curModule.ModuleName), 0);
            }                   
        }
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("KERNEL32.DLL")]                             
        extern public static void Beep(int freq, int dur);      
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    }  
}

如何正确解钩

我不想在记事本

上看到终止符x

那么就不要调用next钩子:

return CallNextHookEx(_hookID, nCode, wParam, lParam);

把它挂接在现有处理程序之前安装自己的处理程序的想法(来自winapi的事务)。通过拦截(就像您已经在做的那样),您不仅可以监听,而且还可以使用该调用调用先前的处理程序。

试试(未测试):

if( vkCode == 88)
{
    ...
    return 0;
}