多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
最近由于项目中需要精确记录某些操作的发生时间,但又没有办法打日志,因此写了个小工具,用来记录当前的毫秒级本机时间。 (程序内部实现了全局钩子,监听所有的键盘事件,即KeyDown,KeyUp事件。) 工具功能如下: ![](image/d41d8cd98f00b204e9800998ecf8427e.png) 1.通过任意键盘按键来记录当前时间 2.可以在列表处单击记录当前时间 C#中对于Hook API的包装如下: using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; namespace HookLib {    public static class HookHelper    {        public delegate int HookProc(            int nCode,            IntPtr wParam,            IntPtr lParam            );        public static int HookCallback( int nCode, IntPtr wParam, IntPtr lParam)        {            if (IntPtr .Zero == HookPtr || null == HookId)            {                return 0;            }            if (nCode >= 0)            {                if (null != HookCallbackEvent)                {                    return HookCallbackEvent(nCode, wParam, lParam);                }            }            return CallNextHookEx(HookPtr, HookId.Value, wParam, lParam);        }        public static IntPtr SetWindowsHookEx()        {            if (null == HookId)            {                throw new Exception( "You must set HookId first!" );            }            HookPtr = SetWindowsHookEx(                HookId.Value,                KeyboardCallback,                Instance,                0);            return HookPtr;        }        public static bool UnhookWindowsHookEx()        {            if (null == HookPtr || IntPtr.Zero == HookPtr)            {                throw new Exception( "HookPtr is null");            }            return UnhookWindowsHookEx(HookPtr);        }        public static int WH_KEYBOARD_LL = 13;        public static IntPtr HookPtr;        public static int? HookId = WH_KEYBOARD_LL;        public static event HookProc HookCallbackEvent;        public static HookProc KeyboardCallback = new HookProc (HookHelper.HookCallback);        public static IntPtr Instance = Marshal.GetHINSTANCE(Assembly .GetAssembly(typeof( HookHelper)).GetModules()[0]);        #region Win32API        [ DllImport("User32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall,            SetLastError = true)]        public static extern IntPtr SetWindowsHookEx(            int idHook,            HookProc lpfn, //如果是全局钩子,回调函数应该就写在dll内            IntPtr hMod,   //如果是全局钩子,应该是包含lpfn方法的dll句柄,注意此句柄要保持生命周期            int dwThreadId //如果是全局钩子,置为0;否则应该是保护lpfn方法的进程id            );        [ DllImport("User32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall,            SetLastError = true)]        public static extern int CallNextHookEx(            IntPtr hhk,            int nCode,            IntPtr wParam,            IntPtr lParam            );        [ DllImport("User32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall,            SetLastError = true)]        public static extern bool UnhookWindowsHookEx(            IntPtr hhk            );        [ DllImport("Kernel32.dll" , CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]        public static extern int GetLastError();        #endregion    } }     HookHelper的用法: 1.可以使用原始的win32 api,如 public static extern IntPtr SetWindowsHookEx(            int idHook,            HookProc lpfn,            IntPtr hMod,            int dwThreadId            ); 2.可以使用包装好的2个方法,只要外部指定要处理的HookId(安装何种类型的钩子),以及处理钩子的回调函数HookCallbackEvent, 如 private void MainView_Loaded (object sender, System .Windows. RoutedEventArgs e )        {            //Add hook            HookHelper.HookCallbackEvent += F5Proc;            HookHelper.HookId = HookHelper. WH_KEYBOARD_LL;            HookHelper.SetWindowsHookEx ();        } 注意事项: 1.如果是全局钩子,请把钩子的回调处理函数放在dll中 2.C#好像不支持wm_keyboard这样的钩子,需要替换为wm_keyboard_ll则可以 3.如果是全局钩子,请务必把进程实例设为回调函数所在dll的实例。 4.请保证回调处理函数的生命周期,要不然被垃圾回收器回收后找不到调用函数。 Demo 下载地址:[http://download.csdn.net/detail/muzizongheng/8390369](http://download.csdn.net/detail/muzizongheng/8390369) [![](image/d41d8cd98f00b204e9800998ecf8427e.png)](#)