2009-11-21 90 views
3

这是我的keyhooking类的代码,但它不起作用。我想知道是否有人能告诉我为什么?我在另一个控制台应用程序中进行实例化。调试消息提供了正确的输出,但键盘钩子根本无法捕获键。我希望有人能告诉我为什么。C#低级键盘挂钩不工作

namespace GlobalHooks 
{ 
    public class InterceptKeys 
    {   
     private const int WH_KEYBOARD_LL = 13; 
     private const int WM_KEYDOWN = 0x0100; 

     private static IntPtr _hookID = IntPtr.Zero; 
     private static String keysHooked = String.Empty; 

     private static LowLevelHookProc keyboardHook; 

     public delegate IntPtr LowLevelHookProc(int nCode, Int32 wParam, IntPtr lParam); 
     public delegate void KeyboardHandleFunction(int vkCode); 
     public static event KeyboardHandleFunction keyHookReturn; 

     public InterceptKeys(KeyboardHandleFunction func) 
     { 
      keyHookReturn = func; 
      keyboardHook = new LowLevelHookProc(HookCallback); 
     } 

     public static void debug() 
     { 
      Console.Write("\n[Success!] _hookID: "+_hookID); 
      Console.Write("\n[Success!] keyboardProc: "+keyboardHook.ToString()); 
     } 

     private IntPtr SetupHook(LowLevelHookProc keyProcess) 
     { 
      using (Process curProcess = Process.GetCurrentProcess()) 
      using (ProcessModule curModule = curProcess.MainModule) 
      { 
       return SetWindowsHookEx(WH_KEYBOARD_LL, keyProcess, 
        GetModuleHandle(curModule.ModuleName), 0); 
      } 
     } 

     public void Hook() 
     { 
      _hookID = SetupHook(keyboardHook); 
      debug(); 
     } 

     public void Unhook() 
     { 
      UnhookWindowsHookEx(_hookID); 
     } 


     public static void OnCallbackReturn(int nCode) 
     { 
      if (keyHookReturn != null) 
      { 
       keyHookReturn(nCode); 
      } 
      else 
      { 
       throw new Exception(); 
      } 
     } 

     public static IntPtr HookCallback(int nCode, Int32 wParam, IntPtr lParam) 
     { 
      Console.WriteLine("Calledback"Wink; 
      if (nCode >= 0 && wParam == WM_KEYDOWN) 
      { 
       int vkCode = Marshal.ReadInt32(lParam); 
       Console.WriteLine((Keys)vkCode); 
       OnCallbackReturn(nCode); 
      } 
      return CallNextHookEx((int)_hookID, nCode, wParam, lParam); 
     } 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelHookProc lpfn, IntPtr hMod, uint dwThreadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr CallNextHookEx(int hhk, int nCode, int wParam, IntPtr lParam); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr GetModuleHandle(string lpModuleName); 
    } 
} 

回答

13

你叫你的Main功能Application.Run

标准控制台线程没有消息循环,这是钩子正常工作所必需的,Application.Run负责处理该消息。

+0

你是一个美丽,美丽的人。祝你梦想成真。 谢谢你,你的解决方案工作完美。 – Overload119 2009-11-22 15:31:53

+0

Application.Run将我的控制台应用放在了繁忙的地方。有没有办法让我继续运行控制台应用程序? – 2013-06-11 12:12:25