2011-10-20 2 views
1

私はグローバルフックを登録する点で非常に似ている2つのコードを持っています。グローバルシェルフックの登録グローバルキーボードフックは機能しますが、グローバルシェルフックは失敗します

public class KeyboardHook : IDisposable 
{ 
    #region Events 
    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 
    public delegate void HookEventHandler(object sender, KeyboardHookEventArgs e); 
    public event HookEventHandler KeyDown; 
    public event HookEventHandler KeyUp; 
    #endregion 

    #region Constants 
    private const int WH_KEYBOARD_LL = 13; 
    private const int WM_KEYDOWN = 0x0100; 
    private const int WM_SYSKEYDOWN = 0x0104; 
    private LowLevelKeyboardProc _proc = null; 
    private static IntPtr _hookID = IntPtr.Zero; 
    #endregion 

    #region Imports 
    [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); 

    #endregion 

    #region Constructor 
    public KeyboardHook() 
    { 
     _proc = new LowLevelKeyboardProc(HookCallback); 
     _hookID = SetHook(_proc); 
    } 

    #endregion 


    #region Methods 
    private IntPtr SetHook(LowLevelKeyboardProc proc) 
    { 
     using (Process curProcess = Process.GetCurrentProcess()) 
     using (ProcessModule curModule = curProcess.MainModule) 
     { 
      return SetWindowsHookEx(WH_KEYBOARD_LL, proc, 
       GetModuleHandle(curModule.ModuleName), 0); 
     } 
    } 

    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     //if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
     if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) 
     { 
      int vkCode = Marshal.ReadInt32(lParam); 
      WinForms.Keys key = (WinForms.Keys)vkCode; 
      if (this.KeyDown != null) 
       this.KeyDown(this, new KeyboardHookEventArgs(vkCode)); 
     } 
     return CallNextHookEx(_hookID, nCode, wParam, lParam); 
    } 

    #endregion 

    #region Destructor 
    public void Dispose() 
    { 
     UnhookWindowsHookEx(_hookID); 
    } 
    #endregion 
} 

は、グローバルなキーボードフックの登録何らかの理由で

public enum ShellEvents 
    { 
     HSHELL_WINDOWCREATED = 1, 
     HSHELL_WINDOWDESTROYED = 2, 
     HSHELL_ACTIVATESHELLWINDOW = 3, 
     HSHELL_WINDOWACTIVATED = 4, 
     HSHELL_GETMINRECT = 5, 
     HSHELL_REDRAW = 6, 
     HSHELL_TASKMAN = 7, 
     HSHELL_LANGUAGE = 8, 
     HSHELL_ACCESSIBILITYSTATE = 11 
    } 

    public class ShellHook 
    { 
     #region Events 
     private delegate IntPtr ShellProc(int nCode, IntPtr wParam, IntPtr lParam); 
     public delegate void HookEventHandler(object sender, ShellHookEventArgs e); 
     public event HookEventHandler WindowActivated; 
     #endregion 

     #region Constants 
     private const int WH_SHELL = 10; 
     private ShellProc _proc = null; 
     private static IntPtr _hookID = IntPtr.Zero; 
     #endregion 

     #region Imports 
     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr SetWindowsHookEx(int idHook, 
      ShellProc 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); 

     [DllImport("user32.dll")] 
     static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); 
     #endregion 

     #region Fields 
     #endregion 

     #region Constructor 
     public ShellHook() 
     { 
      _proc = new ShellProc(HookCallback); 
      _hookID = SetHook(_proc); 
     } 
     #endregion 

     #region Methods 
     private IntPtr SetHook(ShellProc proc) 
     { 
      using (Process curProcess = Process.GetCurrentProcess()) 
      using (ProcessModule curModule = curProcess.MainModule) 
      { 
       return SetWindowsHookEx(WH_SHELL, proc, 
        GetModuleHandle(curModule.ModuleName), 0); 
      } 
     } 

     private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
     { 
      if (nCode >= 0 && wParam.Equals(ShellEvents.HSHELL_WINDOWACTIVATED)) 
      { 
       string windowTitle = GetWindowTitle(wParam); 
       if (this.WindowActivated != null) 
        this.WindowActivated(this, new ShellHookEventArgs(windowTitle)); 
      } 
      return CallNextHookEx(_hookID, nCode, wParam, lParam); 
     } 

     private string GetWindowTitle(IntPtr hWnd) 
     { 
      const int nChars = 256; 
      StringBuilder Buff = new StringBuilder(nChars); 

      if (GetWindowText(hWnd, Buff, nChars) > 0) 
      { 
       return Buff.ToString(); 
      } 
      return null; 
     } 
     #endregion 

     #region Destructor 
     public void Dispose() 
     { 
      UnhookWindowsHookEx(_hookID); 
     } 
     #endregion 
    } 

を、キーボードフックの作品を、しかし、シェルフックは(SetWindowsHookExリターンを失敗し0コールバックには決して到達しません)。

なぜでしょうか?

答えて

2

私は自分の質問に答えると思います。 pinvoke.netからのこの引用は、なぜ...

しかし、あなたは低レベルのフックを除いては、Microsoft .NET Framework でグローバルフックを実装することはできませんについて説明します。グローバルフックをインストールするには、呼び出しに有効で一貫性のある関数を必要とする別の プロセスに注入するために、フックに ネイティブダイナミックリンクライブラリ(DLL)エクスポートが必要です。この には、.NET FrameworkがサポートしていないDLLエクスポートが必要です。管理された コードは、 という関数ポインタの一貫した値の概念を持たない。なぜなら、これらの関数ポインタは、 という動的に構築されたプロキシであるからです。

関連する問題