2013-07-27 65 views
13

我想在項目中使用Gma.UserActivityMonitor庫,並且遇到了我自己無法克服的錯誤。Gma.UserActivityMonitor&SetWindowsHookEx錯誤126

HookManager.Callbacks.cs文件有一個稱爲靜態方法EnsureSubscribedToGlobalMouseEvents用下面的代碼(更多或更少):

var asm = Assembly.GetExecutingAssembly().GetModules()[0]; 
var mar = Marshal.GetHINSTANCE(asm); 
s_MouseHookHandle = SetWindowsHookEx(
    WH_MOUSE_LL, 
    s_MouseDelegate, 
    mar, 
    0); 
//If SetWindowsHookEx fails. 
if (s_MouseHookHandle == 0) 
{ 
    //Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set. 
    int errorCode = Marshal.GetLastWin32Error(); 
    //do cleanup 

    //Initializes and throws a new instance of the Win32Exception class with the specified error. 
    throw new Win32Exception(errorCode); 
} 

SetWindowsHookEx總是返回0和上面的代碼保持拋出異常與消息The specified module could not be found和呼叫到Marshal.GetLastWin32Error返回碼126。我可以成功運行Gma.UserActivityMonitor原始項目提供的演示,但由於我的項目有點太複雜,無法在這裏解釋,所以我無法詳細解釋它與我的區別。我只是希望有人能盲目猜測這個問題。

順便說一句,在該項目的常見問題解答中,有人說當其他人遇到問題時(SetWindowsHookEx返回錯誤),只有在項目調試時才選中Enable Visual Studio hosting process。所以我沒有選擇在我的盒子裏,仍然存在相同的問題,而不僅僅是在調試模式下,而且當我雙擊Windows資源管理器中的發佈文件時(不包括Visual Studio)。

要給更多的信息,在演示項目(工作正常)asm變量指向{Gma.UserActivityMonitor.dll}和我的項目中拋出異常相同!

+0

它可能與所涉及的過程的位數有關... – Yahia

+0

請您解釋更多或指向正確的資源? – Mehran

+0

掛鉤通常涉及一些代碼成爲目標進程的一部分。這可以通過不同的方式來實現,但基本上在你的流程,掛鉤進程和操作系統上的任何差異都會導致問題和/或錯誤行爲。 – Yahia

回答

27

這類代碼在.NET 4及更高版本上無法使用。您得到的錯誤代碼是描述性的,126 =「指定的模塊無法找到」。這告訴你「mar」變量包含垃圾。

.NET 4有一個非常重要的CLR更改,它不再假裝jitted代碼駐留在非託管模塊中。所以Marshal.GetHINSTANCE()不再有效。然後代碼變得不穩定,它忘記檢查返回值,測試它的(IntPtr)-1是檢測失敗和聲明災難所必需的。在Codeproject上找到的代碼很常見,很多bug和sloppiness無法由貢獻者修復。不是SO模型:)

SetWindowsHookEx()對於低級掛鉤有點不方便。它需要一個有效的模塊句柄,並對其進行檢查,但實際上並未使用它。這在Win7 SP1的某個地方得到了修復。雖然當然有意成爲一個有用的修復,但實際上卻讓問題變得更糟。因爲現在它可能在你的開發機器上工作,但不在你的用戶機器上。

Anyhoo,修復很簡單,你只需要咳嗽一個有效的模塊句柄。你可以得到一個從一個模塊是始終存在於管理應用程序,你需要pinvoke LoadLibrary得到它:

var mar = LoadLibrary("user32.dll"); 
s_MouseHookHandle = SetWindowsHookEx(
    WH_MOUSE_LL, 
    s_MouseDelegate, 
    mar, 
    0); 

無需調用FreeLibrary(),該模塊仍加載,直到您的程序結束反正。

+0

感謝漢斯,它工作完美。我只想補充一點,我設法找到了問題。你會成爲我將要使用的解決方案,但如果你願意的話,我只是想問一下你對我的新發現的看法。問題是我的項目的「Platform target」被設置爲x86,而我的操作系統是Windows 7x64。像'x64'和'Any CPU'這樣的其他選擇可以在我的機器上運行,但是無論「Platform target」如何,您的解決方案都能正常工作,所以我打算繼續這樣做,因爲我的解決方案中有用C++編寫的Win32項目。您是否認爲即使在WindowsXP,Vista或Windows 8等其他操作系統中,您的解決方案也很穩固? – Mehran

+0

我在答案中明確指出,讓它在任何Windows版本上工作是目標。 –

+0

對不起,我錯過了。非常感謝。 – Mehran

相關問題