键盘敲击计数器·.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也没有问题。

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