Feeling

              三人行,必有我?guī)熝?/p>

             ::  :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            185 隨筆 :: 0 文章 :: 392 評(píng)論 :: 0 Trackbacks
          SWT-Extension這個(gè)項(xiàng)目做了很久,但一直都沒(méi)有realease,只是個(gè)人做著玩玩,很重要的一個(gè)原因是對(duì)Windows System Hook的機(jī)制沒(méi)有能夠很好地實(shí)現(xiàn)出來(lái)。Hook本身不算是很難的技術(shù),在C++,C#里都能夠很容易的實(shí)現(xiàn),為什么運(yùn)用Java就那么困難呢?

          首先當(dāng)然主要還是我個(gè)人對(duì)C++并不在行了,其次就是Java和C++交互的問(wèn)題了。要想通過(guò)C++把數(shù)據(jù)傳給Java,就要通過(guò)JNI標(biāo)準(zhǔn)的接口來(lái)實(shí)現(xiàn),也就是要通過(guò) JNIENV 來(lái)實(shí)現(xiàn),但是HookProc 這個(gè)CallBack 是給系統(tǒng)進(jìn)程調(diào)用的,不是給你Java調(diào)用的,你說(shuō)系統(tǒng)進(jìn)程調(diào)用了 HookProc 之后,沒(méi)法把這個(gè)事件傳遞給Java,那么還有一個(gè)方法,用Java不間斷的輪循Hook里的數(shù)據(jù),這倒是能實(shí)現(xiàn),網(wǎng)上也有一個(gè)老外的例子,但不好的地方就是當(dāng)我系統(tǒng)沒(méi)工作的時(shí)候,你Java還在那兒輪循我干嘛?這不是浪費(fèi)資源嗎?所以呢,這解鈴還需系鈴人,系統(tǒng)的事件還得讓系統(tǒng)來(lái)通知你才好。在Java里,有一個(gè)IO阻塞,比如當(dāng)調(diào)用System.in.read()的時(shí)候,系統(tǒng)就是等待你的輸入,如果你不輸入,系統(tǒng)就一直等著不工作。還有線程,有wait方法,非要等著其他的線程通過(guò)notify把你喚醒你才能工作。在C++里也有這么一套機(jī)制:CreateEvent 和WaitForSingleObject,也就是說(shuō)我先創(chuàng)建一個(gè)事件,然后將這個(gè)事件置于未激活狀態(tài),讓它一直等待,將線程阻塞住,當(dāng)HookProc被系統(tǒng)進(jìn)程調(diào)用的時(shí)候,就將這個(gè)事件激活,通知Java程序你可以開(kāi)始干活了,干完活以后再次被阻塞,直到這個(gè)Hook被uninstall掉。當(dāng)然這其中還有一些 C++ 代碼的細(xì)節(jié)性問(wèn)題,比如怎么讓不同的進(jìn)程共享同一個(gè)事件,這里要說(shuō)明的就是不同的進(jìn)程可以共享同一個(gè)事件,但是不能共享同一個(gè)事件句柄,同一個(gè)事件,在不同的進(jìn)程里有不同的句柄,句柄是不能跨進(jìn)程的。 

          我個(gè)人認(rèn)為Hook應(yīng)當(dāng)是SWT-Extension里一個(gè)很重要的組成部分,SWT本身只能實(shí)現(xiàn)線程鉤子,對(duì)于系統(tǒng)級(jí)的鉤子無(wú)能為力。因?yàn)橄到y(tǒng)機(jī)鉤子需要實(shí)現(xiàn)數(shù)據(jù)共享操作,還需要DLL入口句柄,這些我已都在SWT-Extension中實(shí)現(xiàn)了。唯一讓我遺憾的是沒(méi)有辦法實(shí)現(xiàn)日志鉤子,這是一個(gè)很有用的鉤子,可以用來(lái)記入當(dāng)前用戶行為的操作,然后重新演示,我想如果做自動(dòng)化測(cè)試這個(gè)會(huì)很有用,或者給游戲軟件練功什么的,呵呵。之所以不能實(shí)現(xiàn)是因?yàn)檫@個(gè)鉤子很特別,它要的不是DLL的句柄,而是應(yīng)用程序的句柄,這沒(méi)有辦法從Java程序里獲得,我試過(guò)javaw.exe,但是也不行,會(huì)導(dǎo)致系統(tǒng)假死。以后有時(shí)間在研究吧。

          做完Hook,終于可以松一口氣,發(fā)一個(gè)小小的realease了,剩下的就是document工作要做了,一個(gè)枯燥無(wú)味的工作,就當(dāng)練習(xí)一下英語(yǔ)好了。

          這里發(fā)一個(gè)Hook的截圖:




          沒(méi)有了標(biāo)題欄的Eclipse
          最新的Build和代碼也可以在 http://feeling.sf.net 上下載了。

          評(píng)論

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了[未登錄](méi) 2007-12-07 17:41 差沙
          樓主佩服,這方面不是很懂, 但一看就是好東東,強(qiáng)帖留名  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-08 03:18 gr8vyguy
          挺好的,只是點(diǎn)File System導(dǎo)致JVM退出。

          其實(shí)我也做了一些這方面的擴(kuò)展。包括Hook。還沒(méi)看你的Hook的怎么實(shí)現(xiàn)的。
          我是用SWT的OS.SetWindowsHookEx + org.eclipse.swt.internal.Callback.
          不需要再定義native的函數(shù)。只是實(shí)現(xiàn)了鍵盤和鼠標(biāo)兩個(gè)鉤子。

          另外你的Registry基本是抄Core Java II里的吧,我做了一套仿C#里Registry的接口的。

          有意的話,我可以把我的代碼捐出來(lái),加到你的Project里!

          還有這個(gè)最好叫SWT Extension on Windows。

            回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了[未登錄](méi) 2007-12-08 11:41 BeanSoft
          支持!  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-08 18:45 三人行,必有我?guī)熝?/a>
          To:gr8vyguy
          我知道你的Hook的做法,不過(guò)那只能實(shí)現(xiàn)線程鉤子,我想實(shí)現(xiàn)的是系統(tǒng)全局鉤子,不是一個(gè)概念。Core Java II 我沒(méi)有看過(guò),不知道里面有Registry的實(shí)現(xiàn)。File System導(dǎo)致JVM退出,遺留的Bug,暫時(shí)不知道怎么解決。  
          回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-09 04:03 gr8vyguy
          @三人行,必有我?guī)熝?br>我實(shí)現(xiàn)的是絕對(duì)是系統(tǒng)全局鉤子。

          Registry? 那就奇怪了,我再仔細(xì)看看,如果搞錯(cuò)了那就不好意思了。

            回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-09 13:32 cnfree
          @gr8vyguy
          全局鈎子嗎?不可能用swt實(shí)現(xiàn)的,因?yàn)闆](méi)有dll的handle,是無(wú)法實(shí)現(xiàn)數(shù)據(jù)共享的。如果你確信你真的實(shí)現(xiàn)了,拜托你給我一個(gè)例子,不甚感激。你說(shuō)的那種方法我很久以前就嘗試過(guò)了,但是沒(méi)有搞定。

          http://www.aygfsteel.com/cnfree/archive/2006/11/27/83754.html ,我以前的一篇文章,當(dāng)時(shí)以為實(shí)現(xiàn)了,后來(lái)發(fā)現(xiàn)數(shù)據(jù)在Java的HookProc里無(wú)法共享,也就是說(shuō),你能拿到 LParam,但是取不出相關(guān)數(shù)據(jù),只能用用WParam,因此就算你可以實(shí)現(xiàn)全局鉤子,你說(shuō)的那種Case是無(wú)法獲得所有的信息。

          別人的文章:http://www.javaworld.com.tw/jute/post/view?bid=35&id=175440&sty=3&age=0

          PS:我已經(jīng)做成了插件,可以直接在插件開(kāi)發(fā)中使用了。  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-09 20:26 gr8vyguy
          @cnfree
          沒(méi)有全局的鉤子我的抓圖軟件怎么實(shí)現(xiàn)
          http://www.aygfsteel.com/xilaile/archive/2007/05/02/114983.html

          普通的鉤子函數(shù)的確需要定義在獨(dú)立的DLL中才能掛進(jìn)去,不過(guò)你不要忘了還存在一類Low Level的鉤子,不需呀dll的
            回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-10 11:47 三人行,必有我?guī)熝?/a>
          @gr8vyguy
          沒(méi)有JDK1.6,所以運(yùn)行不起來(lái),但是看過(guò)了你的代碼。
          1,你添加了2個(gè)native方法:
          static final native boolean InstallMouseHook(int i, int j);
          static final native boolean UninstallMouseHook(int i);
          所以我不能從你的程序里斷定你用的是哪種鉤子
          2,和我上個(gè)回復(fù)所說(shuō)的一樣,你只是使用了wParam,沒(méi)有用到lParam,
          wParam 包含了Mouse行為信息, lParam則是一個(gè)MSLLHOOKSTRUCT結(jié)構(gòu)體指針,我想你應(yīng)該是不能夠根據(jù)這個(gè)指針拿到結(jié)構(gòu)體的,而MSLLHOOKSTRUCT可以用來(lái)拿到坐標(biāo)信息。其實(shí)就對(duì)窗口某一部位截圖而言,根本就不需要Hook,SWT+Swing的Robot就可以實(shí)現(xiàn)了。

          好了不用再爭(zhēng)論了,Mouse Hook自有 Mouse_LL沒(méi)有的優(yōu)勢(shì),可以在98下運(yùn)行,保證了系統(tǒng)兼容性。畢竟連純C#也只能實(shí)現(xiàn)Mouse_LL和Keyboard_LL兩種Hook。

          我現(xiàn)在還有點(diǎn)問(wèn)題,就是如果我要攔截Hook,比如我以前的一個(gè)需求,攔截一個(gè)瀏覽器的菜單讓它不顯示出來(lái),如果瀏覽器嵌在Java程序內(nèi)部,那么在Java內(nèi)部的HookProc正好處理這個(gè)事件,但是如果攔截的外部的瀏覽器,又該如果解決。  
          回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-10 15:26 gr8vyguy
          HookProc應(yīng)該先于WindowProc, 判斷一下,不下傳不就行了  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-10 16:38 三人行,必有我?guī)熝?/a>
          @gr8vyguy
          是的,關(guān)鍵是現(xiàn)在的Hookproc是在C++里實(shí)現(xiàn)的,和Java完全沒(méi)有關(guān)系,如果在Java實(shí)現(xiàn),就無(wú)法數(shù)據(jù)共享了。但是判斷是否下傳的邏輯是在Java里,我在考慮怎么把這兩者結(jié)合起來(lái)。  
          回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-12 17:18 leigh
          可以使用 DuplicateHandle 來(lái)實(shí)現(xiàn)跨進(jìn)程的句柄。
            回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2007-12-12 18:21 三人行,必有我?guī)熝?/a>
          跨進(jìn)程我已經(jīng)實(shí)現(xiàn)了,在Java里攔截JNI的HookProc,并對(duì)數(shù)據(jù)做出一些修改,這才是困難所在。  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2008-01-08 18:02 黑靈
          good job  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2008-05-16 22:08 brucehu
          請(qǐng)問(wèn)你那個(gè)不需要jre的程序是怎么實(shí)現(xiàn)的  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了 2009-06-20 11:02 狄德羅
          有沒(méi)有SWT linux Extension我想用這個(gè)在linux下實(shí)現(xiàn)窗口失去鍵盤焦點(diǎn)  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了[未登錄](méi) 2012-05-07 13:58 滌生
          哥們你這個(gè)keyproess有bug.一旦遇到系統(tǒng)的alert觸發(fā)的時(shí)候就掛了  回復(fù)  更多評(píng)論
            

          # re: 準(zhǔn)備對(duì)SWT-Extension realease了[未登錄](méi) 2013-11-15 15:13 javapon
          想對(duì)USB做個(gè)監(jiān)聽(tīng),發(fā)現(xiàn)用這個(gè)方法Hook.CALLWNDPROC 有的時(shí)候能監(jiān)聽(tīng)到鼠標(biāo)的拔出和插入, 由于對(duì)C一頭霧水,請(qǐng)問(wèn)如果是這個(gè)方法 ,usb設(shè)備插入和拔出對(duì)應(yīng)的HookData.getMessage是多少,  回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          GitHub |  開(kāi)源中國(guó)社區(qū) |  maven倉(cāng)庫(kù) |  文件格式轉(zhuǎn)換 
          主站蜘蛛池模板: 神池县| 沾化县| 宝山区| 错那县| 翁牛特旗| 即墨市| 绥滨县| 宝应县| 湄潭县| 乐业县| 礼泉县| 金塔县| 镇雄县| 罗山县| 黄山市| 酉阳| 沙湾县| 蓝山县| 台州市| 宣城市| 凤山县| 鸡西市| 南召县| 信宜市| 白山市| 仁布县| 金华市| 三门县| 神农架林区| 信宜市| 黔南| 东山县| 贵溪市| 闸北区| 海宁市| 新闻| 阿勒泰市| 微博| 临夏县| 南木林县| 竹北市|