2023年11月25日发(作者:)
目录
一,BHO开发概述 ............................................................. 2
1.1BHO的用途及实际应用 ................................................ 2
1.2BHO的工作原理及技术环境 ............................................ 2
二,框架设计 ................................................................. 3
2.1构建BHO框架......................................................... 3
2.2实现IOWS的接口方法 ......................................... 4
BJECTITHITE
三,注销SESSION ............................................................. 6
3.1将BHO注册为浏览器的事件处理器 ....................................... 6
3.2监听浏览器关闭事件,并向S发送跳转指令 ........................... 7
ERVER
3.3关闭BHO注销页面 ..................................................... 8
3.4阻止文件浏览器加载BHO ............................................... 9
3.5向注册表中注册BHO组件 ............................................... 9
四,打包发布 ................................................................ 10
4.1BHO打包和找到关联D文件........................................... 10
LL
4.2编写自动安装脚本文件............................................. 11
INF
4.3用工具打包。 .................................................. 11
CABARC
- 1 -
一,BHO开发概述
1.1 BHO的用途及实际应用
BHO(Browser Help Objects),是实现了特定接口的COM组件。BHO只适用于Windows系统下
的IE浏览器和文件浏览器。开发好的BHO插件在注册表特定的位置注册好后,每当微软的浏览器启
动,BHO实例就会被创建。在浏览器工作的过程中,BHO会接收到很多事件,比如浏览器浏览新的地
址、前进或后退、生成新的窗口、浏览器退出等等。BHO可以在这些事件的响应中实现与浏览器的
交互。
本文档中我们将通过编写一个BHO实例来详细讲解BHO开发的一般流程。该实例的功能是:当
用户成功登陆网站后,如果用户点击IE关闭按钮,BHO将捕获IE关闭事件,同时向Server发送一
个注销当前用户Session的请求。Server注销后跳转到BHO注销页面,BHO捕获到BHO注销页面时,
关闭该页面。
1.2 BHO的工作原理及技术环境
BHO是COM组件,而且一定实现了IObjectWithSite接口。这些组件除了在注册表中注册为COM
Server外,还必须将它们的CLSID在HKEY_LOCAL_MACHINESOFTWARE Windows CurrentVersion
ExplorerBrowser Helper Objects下注册为子键。微软在设计浏览器的时候,已经给这些组件预
留了空间。每当浏览器启动时,浏览器会首先在上述注册表位置查看是否有注册的 BHO CLSID;如
果有则分别创建一个实例,并对BHO实例进行初始化,建立交互连接。(注:BHO实例只有在创建它
的浏览器窗口销毁时才被释放。)图1.1演示了BHO的创建过程:
图1.1
- 2 -
表1.1 BHO支持的操作系统一览及IE一览
IE版本 操作系统版本 支持BHO
4.00
5.00
6.00
7.00
Windows 95 and Windows NT 4.0 仅IE4.0
Windows2000 IE和文件浏览器
WindowsXP IE和文件浏览器
Vista IE和文件浏览器
二,框架设计
2.1 构建BHO框架
开发环境: Microsoft Visual C++ 6.0
步骤1:建立一个工作区(WorkSpace)。
步骤2:在工作区中,建立一个 ATL 工程(Project)。示例程序叫TEST,并选择
DLL方式,见图2.1。
图2.1
- 3 -
步骤3:增加ATL对象类。在菜单 InsertNew ATL (或者用鼠标右键在
ClassView 卡片中弹出菜单)并选择Object 分类,选中 Internet Exploer 项
目。见图2.2。
图2.2
步骤4:填写COM类的名称。只要输入Short Name,其它自动生成。见图2.3。
图2.3
2.2实现IObjectWithSite的接口方法
步骤1:先定义几个成员变量:CComQIPtr mWebBrowser2,(需要加入#include "ExDisp.h"),用以保存浏览器组件的指针;DWORD mCookie,用以保存与浏览器的连接ID。见图2.4 - 4 - 变量声明 图2.4(详见MyBho.h文件) 步骤2:IObjectWithSite有两个接口方法:SetSite和GetSite。我们只需重载 SetSite 就行了。在ImyBho中增加函数声明SetSite函数。见图2.5 图2.5 步骤3: 实现IDispatch接口方法。事件处理也就在IDispatch::Invoke中实现(各个事 件的ID在ExDispID.h中定义)。 BHO可能会接收到很多事件,但我们只需要响应我们感 兴趣的那一部分。首先在ImyBho中增加该函数的声明。见图2.6 - 5 - 图2.6 步骤4: ImyBho添加RegisterEventHandler(BOOL inAdvise)方法声明,实现向IE注 册和注销事件。详见附录代码。 通过上面的步骤,一个基本的BHO对象框架已经建立起来了。下一节来我们将根据具体要 实现的功能(向Server发送注销Session命令)对代码主要功能作说明。 三,注销Session 3.1将BHO注册为浏览器的事件处理器 注册BHO的事件的工作主要在SetSite函数中来完成。首先保存浏览器指针到mWebBrowser2成 员变量中去。然后调用RegisterEventHandler函数向浏览器注册为事件处理器。见图3.1 /************************************************************ 说明:SetSite(IUnknown *pUnkSite)是IObjectWithSite接口的方法。 功能:1.保存浏览器组件指针, 向浏览器注册为事件处理器。 ************************************************************/ STDMETHODIMP CMyBho::SetSite(IUnknown *pUnkSite){ if (pUnkSite){ //保存浏览器指针到mWebBrowser2成员变量中去。 mWebBrowser2 = pUnkSite; if (mWebBrowser2){ //向浏览器注册为事件处理器。 return RegisterEventHandler(TRUE); } } return E_FAIL;} - 6 - /********************************************************** 说明:自定义函数,用以注册/注销BHO事件。 功能:根据传入的参数TRUE/FALSE来向浏览器注册/注销BHO事件。 **********************************************************/ STDMETHODIMP CMyBho::RegisterEventHandler(BOOL inAdvise) { CComPtr // 得到浏览器的连接点 CComQIPtr HRESULT hr = spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP); if (FAILED(hr)){ return hr; } if (inAdvise){ // 向浏览器注册事件。 hr = spCP->Advise(reinterpret_cast }else{ // 向浏览器注销事件。 spCP->Unadvise(mCookie); } return hr; } 图3.1(详见文件) 3.2监听浏览器关闭事件,并向Server发送跳转指令 监听浏览器事件,全部在Invoke函数中来完成。当捕获了浏览器退出事件(DISPID_ONQUIT) 时,首先取得页面的窗口名,判读是不是成功登陆页面。如果是,向Server 的LogOffAction发送 一组数据,通知Server是BHO注销事件。然后退出IE。见图3.2 case DISPID_ONQUIT: { //取得当前页面的标题。 BSTR lpHader = NULL; mWebBrowser2->get_LocationName(&lpHader); //如果是标题是“登录成功页面”的话,说明用户关闭的是已经登录的主页。 if (strstr( "登录成功页面", OLE2CA(lpHader))){ //需要跳转到Server的LogOutAction中去的URL。 LPTSTR hostUrl = _T("localhost:8080/LogOff/"); //向Server发送"action=BhoLogoff",提示是BHO注销事件。 LPTSTR postData = _T("action=BhoLogoff"); - 7 - //取得POST数据长度。 int size = WideCharToMultiByte(CP_ACP, 0, A2COLE(postData), -1, 0, 0, 0, 0); //为调用Navigate2方法定义参数。 VARIANT vURL; VARIANT vFlags; VARIANT vPostData; VARIANT vHeaders; VARIANT vNull; //此处略去给参数赋值的代码,详见中的Invoke函数。 ……………………………………………….. //跳转函数,并向Server发送数据。 mWebBrowser2->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders); } //注销BHO事件处理器。 RegisterEventHandler(FALSE); break; } 图3.2(详见文件) 3.3关闭BHO注销页面 当Server监听到BHO发来的注销命令时,Server注销当前用户的Session后,跳转到一个专 门的BHO注销页面(正常情况下是注销退出到登陆页面)。当BHO检测到IE已经跳转到BHO注销页面 时,就将窗口关闭。从而使用户对于注销过程可以忽视。见图3.3。 图3.3(详见文件) } break; } mWebBrowser2->Quit(); } case DISPID_NAVIGATECOMPLETE2://监听页面跳转完毕事件 {//参数合法性检查 if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT)){ char * strurl; CComVariant varURL(*pDispParams->rgvarg[0].pvarVal); Type(VT_BSTR); strurl = OLE2A(l); //如果发现当前的URL是BHO注销页面,则关闭当前页面 if (strstr("localhost:8080/LogOff/", strurl)){ - 8 - 3.4阻止文件浏览器加载BHO 为了阻止文件浏览器加载BHO,在Dll入口函数DllMain中加入了判断。见图3.4 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH){ TCHAR pszLoader[MAX_PATH]; GetModuleFileName(NULL, pszLoader, MAX_PATH); _tcslwr(pszLoader); //检查是谁在载入,如果是文件浏览器,则退出。 if (_tcsstr(pszLoader, _T(""))) { return FALSE; } _(ObjectMap, hInstance, &LIBID_TESTLib); DisableThreadLibraryCalls(hInstance); }else if (dwReason == DLL_PROCESS_DETACH){ _(); } return TRUE; // ok } 图3.4(详见文件) 3.5向注册表中注册BHO组件 为了向注册表中注册BHO组件,还需要在中加入下面的代码。见图3.5 图3.5(详见文件) HKLM{ SOFTWARE{ Microsoft{ Windows{ CurrentVersion{ Explorer{ 'Browser Helper Objects'{ {E5155767-23E5-4142-A63B-4DA81B196C36}} } } } } } } 到此,一个简单的注销Seesion的BHO插件开发完毕了,当然还要在根据具体情况,在Server 端加以判断才行。详细代码,请参考附录。 四,打包发布 经过前面的工作,这个BHO可以打包成CAB格式发布到网站了。当然还要在CAB包中编写一个 自动安装的脚步。当用户登录网站,就可以自动安装插件了。下面是详细步骤。 4.1 BHO打包和找到关联Dll文件 首先,把BHO打包成Dll文件。在VC的Build菜单中选择 Set Active Project Configuration 选项,然后再选中Win32 Release MinDependency选项,点击OK。如果此时编译发布出现error LNK2001 错误的话,请到Project->Settings->C/C++中去除_ATL_MIN_CRT这个预处理符号。好了, 如果一切顺利的话。我们编译的Dll文件就存放到了我们的工程下的ReleaseMinDependency目录中 了 。 接下来,由于我们的Dll用到了一些VC自带的Dll库文件。而用户不一定有这些库文件,所 有要找到到底用了哪些库文件。这里我们使用VC自带的工具Dependency。(..Microsoft Visual StudioCommonTools目录下)。使用它打开我们刚编译好的Dll文件,就可以看到和它关联的所有 Dll文件。见图4.1 图4.1 - 10 - 从图中可以看到,当前的Dll用到的VC库文件是 ,。然后我们在 Windows/System32目录下找到这两个个文件,复制。然后和生成的放到一个文件夹。 4.2编写自动安装脚本inf文件 由于我们的CAB包要自动下载安装到用户的电脑上面,所有必须要编写一个inf安装脚本。关 于inf自动安装脚本的说明,详见图4.2 固定格式 此处声明都有哪些文 件。注意顺序,被调用 的dll要放到前面。 1. file值告诉ie到哪里去得到这个dll 2. 第二部分告诉声明支持的OS 3. 第三部分是CPU类型 4. thiscab说明在当前的cab文件 是否需要注册 Dll的CLSID。在VC 中的rgs文件中可以 找到。 图4.2 4.3用cabarc工具打包。 dll将要存到本地硬盘的位置,如果它的值是10, 则将dll放到Windows或者WinNT下;如果是11, 则放到WindowsSystem或者 WinNTSystem32 下;如果是空(就是没有值)则会放到Windows 或者WinNT下的Downloaded Program Files目录 下; 下载此工具/yule/meinv/179/ 把刚才的文件都拷贝到该工具的BIN目录下面。执行如下命令: cabarc –s 6144 N 。执行完毕后,会在此目录下生成一个包。 这个压缩包就可以发布到网站了。当然现在这个包没有经过任何签名,在IE的默认安全策略下面是 执行不了的,解决办法是:1.把放包的网站设置为信任站点。 2.花钱买一个证书,一年费用好像是 5000多。当然我们是测试,所有采用第一种方式。 - 11 - 编写一个HTML文件,插入以下代码: <OBJECT ID="BhoTest" CLASSID="CLSID: E5155767-23E5-4142-A63B-4DA81B196C36" CODEBASE="">OBJECT> 然后把 放到网站目录下。运行见图4.3 图4.3 由于没有获取认证,所以弹出警告框。点击安装后,我们的文件就被复制到了 Windows/Systeme32的目录下面了。并且已经注册。再重启IE,我们的BHO就开始运行了。 注:如需要删除BHO。请用 regsvr32 –u “文件路径 + 文件名”来注销。然后就可以删除掉了。 - 12 -
发布评论