鍵盤敲擊計數器·.NET中實現Global Hook

自從開始做現在這份工作以後,發現自己敲鍵盤明顯增多,日常工作就是以編程以及type in各種各樣東西爲主,抑或就是在MSN Messenger上“筆談”,以致我覺得我的鍵盤都有些承受不了了,“Alt”鍵有些粘滯。所以我打算短期內去買一個微軟人體工學鍵盤,應該會對我的手腕和手指有好處。突然我又想到,很想知道一下我每天敲擊鍵盤多少下。搜索了一下Google沒有找到什麼有關的結果,就自己用C#寫了一個小程序來統計鍵盤敲擊次數,每一次KeyUp算作一次敲擊:

o_KeystrokeCounter.JPG

寫的時候用的是SetWindowsHookEx函數。但運行後發現抓不住這個counter程序以外其他進程中的鍵盤敲擊,查到一片KB318804 “HOW TO: Set a Windows Hook in Visual C# .NET”,心涼了半截:裏面說,“You cannot implement global hooks in Microsoft .NET Framework. To install a global hook, a hook must have a native dynamic-link library (DLL) export to inject itself in another process that requires a valid, consistent function to call into. This requires a DLL export, which .NET Framework does not support. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically”,簡單翻譯過來說,因爲.NET的DLL沒法被unmanaged code的進程調用,所以.NET無法寫全局鉤子。

於是不甘心,繼續找,在Code Project裏面找到一篇文章“Global System Hooks in .NET”,它能在.NET裏面實現全局鉤子,用的方法是中間夾了一層,managed DLL<--unmanaged DLL<--其他進程。這種做法也挺容易理解的,無非是多做了一層界面出來。我不喜歡這樣,原因和接下去一篇文章的作者講到的一樣,“but what I dislike there is an unmanaged DLL in C++ that is a main part of this solution. This unmanaged DLL in C++ and a number of classes make it complicated to integrate it in my own tiny application”。

繼續找,終於找到一篇“Processing Global Mouse and Keyboard Hooks in C#”,它沒有用增加一層unmanaged界面的方法,用的全部是.NET的。用它提供的方法,可以捕捉到全局的鍵盤和鼠標事件。當然,這並不代表那篇KB錯了,只是作者發現那篇KB有兩個例外:WH_KEYBOARD_LL和WH_MOUSE_LL是可以在.NET裏面用的全局鉤子。剩下的就簡單了,把它的source code下載下來,review一下,然後外面加一層殼,做成floating window和托盤圖標,就可以用了。在我的機器上,Performance也沒有問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章