2012-01-28 131 views
0

我試圖捕獲創建/銷燬另一個應用程序的指定窗口的事件。爲此我設置了WM_SHELLHOOKWPF應用程序中的全局shell鉤子

這裏是我的WPF應用程序siplified代碼:

public delegate IntPtr ProcDelegate(int hookCode, IntPtr wParam, IntPtr lParam); 

[DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr SetWindowsHookEx(
    int hookId, ProcDelegate handler, IntPtr hInstance, uint threadId); 
[DllImport("kernel32.dll", SetLastError = true)] 
public static extern IntPtr GetModuleHandle(string lpModuleName); 

private void buttonClick(object sender, RoutedEventArgs e) 
{ 
    IntPtr hookHandler; 

    using (Process curProcess = Process.GetCurrentProcess()) 
    using (ProcessModule curModule = curProcess.MainModule) 
    { 
     var moduleHandle = GetModuleHandle(curModule.ModuleName); 
     hookHandler = SetWindowsHookEx(
      10 /*WH_SHELL*/, shellHookHandler, moduleHandle, 0); 
    } 

    if (hookHandler == IntPtr.Zero) 
    { 
     // Get here error 1428 (ERROR_HOOK_NEEDS_HMOD) - 
     // "Cannot set nonlocal hook without a module handle." 
     throw new Exception(Marshal.GetLastWin32Error().ToString()); 
    } 
} 

private IntPtr shellHookHandler(int hookCode, IntPtr wParam, IntPtr lParam) 
{ 
    // Some code... 
    return IntPtr.Zero; 
} 

的問題是,SetWindowsHookEx總是返回0和最後一個錯誤是

1428(ERROR_HOOK_NEEDS_HMOD)無法設置非掛鉤沒有模塊 處理。

我看了另一個相關的問題。當我爲鼠標,鍵盤等設置鉤子 - 一切正常。

請指出如何解決此錯誤。謝謝。

回答

1

掛鉤的MSDN documentation說「如果應用程序爲不同應用程序的線程安裝鉤子過程,則該過程必須位於DLL中。」

這是因爲你的DLL被加載到另一個應用程序的地址空間中;您需要找到一些機制(例如內存映射文件)將信息傳遞給主應用程序。

但是,與大多數文檔(提到的是here)相反,鍵盤和鼠標鉤子在沒有DLL的情況下工作。這就是他們爲你工作的原因。