應用程序X繼續執行
例如CBT鉤子(window創建等等)的鉤子類型並不切換上下文對於這些類型的鉤子過程大致如下
應用程序X擁有焦點並執行
應用程序X創建一個窗口
Windows用在應用程序X進程空間中的CBT事件消息參數調用鉤子回調函數
應用程序X繼續執行
這應該說明了為什麼某種類型的鉤子能夠用這個庫結構工作而一些卻不能記住這正是該庫要做的在上面第步和第步之後分別插入下列步驟
Windows調用鉤子回調函數
目標回調函數在非托管的DLL中執行
目標回調函數查找它的相應托管的調用代理
托管代理被以適當的參數執行
目標回調函數返回並執行相應於指定消息的鉤子處理
第三步和第四步因非切換鉤子類型而注定失敗第三步將失敗因為相應的托管回調函數不會為該應用程序而設置記住這個DLL使用全局變量來跟蹤這些托管代理並且該鉤子DLL被加載到每一個進程空間但是這個值僅在放鉤子的應用程序進程空間中設置對於另外其它情況它們全部為null
Tim Sylvester在他的《Other hook types》一文中指出使用一個共享內存區段將會解決這個問題這是真實的但是也如Tim所指出的那些托管代理地址對於除了放鉤子的應用程序之外的任何進程是無意義的這意味著它們是無意義的並且不能在回調函數的執行過程中調用那樣會有麻煩的
因此為了把這些回調函數使用於不執行上下文切換的鉤子類型你需要某種進程間的通訊
我已經試驗過這種思想使用非托管的DLL鉤子回調函數中的進程外COM對象進行IPC如果你能使這種方法工作我將很高興了解到這點至於我的嘗試結果並不理想基本原因是很難針對各種進程和它們的線程(CoInitialize(NULL))而正確地初始化COM單元這是一個在你可以使用COM對象之前的基本要求
我不懷疑一定有辦法來解決這個問題但是我還沒有試用過它們因為我認為它們僅有有限的用處例如CBT鉤子可以讓你取消一個窗口創建如果你希望的話可以想像為使這能夠工作將會發生什麼
鉤子回調函數開始執行
調用非托管的鉤子DLL中的相應的鉤子回調函數
執行必須被路由回到主鉤子應用程序
該應用程序必須決定是否允許這一創建
調用必須被路由回仍舊在運行中的鉤子回調函數
在非托管的鉤子DLL中的鉤子回調函數從主鉤子應用程序接收到要采取的行動
在非托管的鉤子DLL中的鉤子回調函數針對CBT鉤子調用采取適當的行動
完成鉤子回調函數的執行
這不是不可能的但是不算好的我希望這會消除在該庫中的圍繞被允許的和受限制的鉤子類型所帶來的神秘
七其它
◆庫文檔我們已經包含了有關ManagedHooks類庫的比較完整的代碼文檔當以Documentation構建配置進行編譯時這被經由Visual StudioNET轉換成標准幫助XML最後我們已使用NDoc來把它轉換成編譯的HTML幫助(CHM)你可以看這個幫助文件只需簡單地在該方案的解決方案資源管理器中點擊Hookschm文件或通過查找與該文相關的可下載的ZIP文件
◆增強的智能感知如果你不熟悉Visual StudioNET怎樣使用編譯的XML文件(preNDoc output)來為參考庫的工程增強智能感知那麼讓我簡單地介紹一下如果你決定在你的應用程序中使用這個類庫你可以考慮復制該庫的一個穩定構建版本到你想參考它的位置同時還要把XML文檔文(SystemHooks\ManagedHooks\bin\Debug\KennedyManagedHooksxml)復制到相同的位置當你添加一個參考到該庫時Visual StudioNET將自動地讀該文件並使用它來添加智能感知文檔這是很有用的特別是對於象這樣的第三方庫
◆單元測試我相信所有的庫都應有與之相應的單元測試既然我是一家公司(主要負責針對NET環境軟件的單元測試)的合伙人和軟件工程師任何人不會對此感到驚訝因而你將會在名為ManagedHooksTests的解決方案中找到一個單元測試工程為了運行該單元測試你需要下載和安裝HarnessIt這個下載是我們的商業單元測試軟件的一個自由的試用版本在該單元測試中我對這給予了特殊的注意在此處方法的無效參數可能導致C++內存異常的發生盡管這個庫是相當簡單的但該單元測試確實能夠幫助我在一些更為微妙的情況下發現一些錯誤
◆非托管的/托管的調試有關混合解決方案(例如本文的托管的和非托管的代碼)最為技巧的地方之一是調試問題如果你想單步調試該C++代碼或在C++代碼中設置斷點你必須啟動非托管的調試這是一個Visual StudioNET中的工程設置注意你可以非常順利地單步調試托管的和非托管的層但是在調試過程中非托管的調試確實嚴重地減慢應用程序的裝載時間和執行速度
八最後警告
很明顯系統鉤子相當有力量然而使用這種力量應該是有責任性的在系統鉤子出了問題時它們不僅僅垮掉你的應用程序它們可以垮掉在你的當前系統中運行的每個應用程序但是到這種程度的可能性一般是很小的盡管如此在使用系統鉤子時你還是需要再三檢查你的代碼
我發現了一項可以用來開發應用程序的有用的技術它使用系統鉤子來在微軟的虛擬PC上安裝你的喜愛的開發操作系統的一個拷貝和Visual StudioNET然後你就可以在此虛擬的環境中開發你的應用程序用這種方式當你的鉤子應用程序出現錯誤時它們將僅退出你的操作系統的虛擬實例而不是你的真正的操作系統我已經不得不重啟動我的真正的OS在這個虛擬OS由於一個鉤子錯誤崩潰時但是這並不經常
注意如果你在網上訂閱了一個MSDN那麼在你整個訂閱過程中你可以自由使用虛擬PC
[] [] [] [] []
From:http://tw.wingwit.com/Article/program/net/201311/15481.html