原文URL: http://blog.csdn.net/u012859646/article/details/16840309 [2009]
在unbuntu或其它linux桌面下运行baidu hi,在hi未推出linux版本前,两种常用的方式为1) wine; 2)虚拟机。
方法1和wine及gcc等版本都有关系,步骤也较多,不一定能成功;就算成功运行,一般也有速度慢的问题,而且hi的某些功能也无法顺利使用。
方法2,使用虚拟机的最主要缺点就是两个系统间切换及共享较为不便,无论你的虚拟机使用的是窗口或是全屏模式。
本文介绍的方法是在virtual box虚拟机基础上的hi使用,介绍了使用过程中的两个问题:
1 virtual box的addition功能: seamless windows、文件及clipboard共享等
2 对hi做了点小定制以便解决此过程发现的一个小问题
一 安装
virtual box里带的 Guest Additions功能是很强大的,在安装了此功能后才能实现我们要做的事。 Guest Additions功能默认是未安装(至少在我用的版本上如此),不过其安装包是附带的,文件名为VBoxGuestAdditions.iso,默认的位置应该是 /usr/share/virtualbox/VBoxGuestAdditions.iso
;如果安装路径不同,可以locate或find一下。
可以先mount一下,这个iso
$ sudo mount -o loop /usr/share/virtualbox/VBoxGuestAdditions.iso /media/cdrom0/
之后,安装
$sudo sh ./VboxLinuxAdditions-x86.run
安装后需重启virtual box。帮助文档里只要这一步安装就可以完成。实际操作中,发现在虚拟的window环境中也要安装对应的Guest Additions才能工作。具体,可以在虚拟机 “管理->虚拟介质管理“菜单中选择 VboxGuestAdditions.iso。即可在虚拟的window环境中,从光盘进行安装。安装之后也需重启window。到此,所有准备工作就已完成。
重启虚拟的window后,ctrl+L就可以进入seamless window模式,如下图,
可以看出,这种模式下和wine的效果其实是类似的,另外虚拟机上的其它应用也都不需变化,就可以直接像一个linux的桌面程序一样使用,如你也可以使用其它流行的输入法或使用ie。如上图linux 下的gvim和window下的hi,就像在同一个桌面上运行。
之前提到的clipboard和文件共享的操作也简单,只需在virtual box下配置即可。
> net use x: \\vboxsvr\vb
即可用x盘符来访问linux机器下的共享文件夹。
二 定制
以上的过程是比较简单的。不过,使用中发现这么个问题。见下图。
就是hi的左边,经常会出一个黑色的窗口,而且有时在hi最小化以后,此“黑块”还是“挥之不去”,甚是烦人。这个窗口,应该是鼠标在好友上悬停时,展示的一个详情窗口,会展示用户最新文章等。可能是hi或virtual box在某个细节处理上的问题,导致了这个黑块。 这个功能于我没有太明显的用处,因为好友最新动态里也有相关内容。
现在想做的就是去掉这个窗口。由于已经若干年没动过window下的相关开发,下面的过程并不算顺利,因为手生的缘故。
红框所示就是正在highligh中的隐藏窗口,可以看出,这个窗口标题Dialog.MainFrame.CradTipWindow。窗口定位后,后续定位窗口生成的代码才较方便。
0012FBE4 10068104 /CALL 到 ShowWindow 来自 Basement.100680FE
0012FBE8 0035026C |hWnd = 0035026C ('Dialog.MainFrame.CradTipWindow',class='BaseGui',parent=000303E4)
0012FBEC 00000008 \ShowState = SW_SHOWNA
从窗口标题可以确认, 这个窗口就是我们关注的“黑块”。另外,由于“应用程序通过调用清除了WS_VISIBLE标志的CteateWindow函数来创建主窗口函数,并且随后调用带SW_SHOW标志的ShowWindow函数来显示窗口”是创建窗口的常用方式。而且从其它断点得到的信息,如CreateWindowExW中,可以了解到,此窗口的创建确实使用了常规的方案。而且,正是这个ShowWindow调用将窗口的WS_VISIBLE属性置上。
#define SW_HIDE 0
#define SW_SHOWNA 8
可见,原程序中,调用ShowWindow的参数为数值8,我们希望将其改成0(不可见)
上图中Basement是指hi调用的是basement.dll中的函数,这个dll中应该是封装了不少常规调用。一般来说,对ShowWindow API应该也会做点封装,所以可以在附近几个栈帧中查看。在ShowWindow调用往上的第二个帧中,可以看到如下汇编代码:
005446C6 6A 08 PUSH 8
005446C8 50 PUSH EAX
005446C9 FF91 C8000000 CALL DWORD PTR DS:[ECX+C8]
此处的 push 8,很可能就是将参数SW_SHOWA进栈。当然,这个可以从汇编代码的参数去证实。从这个代码猜测API ShowWindow往上的第一个函数,带两个参数,其中8是第二个参数。因为,无论是cdecl或stdcall,函数参数都是从右向左入栈。
再重新生成一个exe程序。测试一下,果然,悬停好友时,不再出现提示框。在linux桌面下的小“黑块”也随之消失了!
三 总结
本文介绍了在unbuntu下使用virtual box的 seamless window运行hi的办法,同时通过打patch的办法解决了hi和virtual box兼容上的一个小问题。本文也可以作为修改没有代码的二进制程序的一个小demo。当然,本例可能比较简单,相信本方案也不是解决这个问题的最好办法, 权当一个用技术手段定位解决实际问题的例子吧。
2009
--EnD--