VC制作BHO

 

目录

一,BHO开发概述. 3

1.1  BHO的用途及实际应用. 3

1.2  BHO的工作原理及技术环境. 3

二,框架设计. 4

2.1 构建BHO框架. 4

2.2实现IObjectWithSite的接口方法. 5

三,注销Session 7

3.1将BHO注册为浏览器的事件处理器. 7

3.2监听浏览器关闭事件,并向Server发送跳转指令. 8

3.3关闭BHO注销页面. 9

3.4阻止文件浏览器加载BHO 9

3.5向注册表中注册BHO组件. 10

四,打包发布. 10

4.1 BHO打包和找到关联Dll文件. 10

4.2编写自动安装脚本inf文件. 11

4.3用cabarc工具打包。. 12

 

 

 

 

 

 

一,BHO开发概述

1.1  BHO的用途及实际应用

BHOBrowser Help Objects),是实现了特定接口的COM组件。BHO只适用于Windows系统下的IE浏览器和文件浏览器。开发好的BHO插件在注册表特定的位置注册好后,每当微软的浏览器启动,BHO实例就会被创建。在浏览器工作的过程中,BHO会接收到很多事件,比如浏览器浏览新的地址、前进或后退、生成新的窗口、浏览器退出等等。BHO可以在这些事件的响应中实现与浏览器的交互。

本文档中我们将通过编写一个BHO实例来详细讲解BHO开发的一般流程。该实例的功能是:当用户成功登陆网站后,如果用户点击IE关闭按钮,BHO将捕获IE关闭事件,同时向Server发送一个注销当前用户Session的请求。Server注销后跳转到BHO注销页面,BHO捕获到BHO注销页面时,关闭该页面。

 1.2  BHO的工作原理及技术环境

BHOCOM组件,而且一定实现了IObjectWithSite接口。这些组件除了在注册表中注册为COM Server外,还必须将它们的CLSIDHKEY_LOCAL_MACHINE/SOFTWARE/ Windows/ CurrentVersion/    Explorer/Browser Helper Objects下注册为子键。微软在设计浏览器的时候,已经给这些组件预留了空间。每当浏览器启动时,浏览器会首先在上述注册表位置查看是否有注册的 BHO CLSID;如果有则分别创建一个实例,并对BHO实例进行初始化,建立交互连接。(注:BHO实例只有在创建它的浏览器窗口销毁时才被释放。)图1.1演示了BHO的创建过程:

                    1.1

1.1  BHO支持的操作系统一览及IE一览

IE版本

操作系统版本

支持BHO

4.00

Windows 95 and Windows NT 4.0

IE4.0

5.00

Windows2000

IE和文件浏览器

6.00

WindowsXP

IE和文件浏览器

7.00

Vista

IE和文件浏览器

二,框架设计

2.1 构建BHO框架

n         开发环境: Microsoft Visual C++ 6.0

n         步骤1建立一个工作区(WorkSpace)

n         步骤2在工作区中,建立一个 ATL 工程(Project)。示例程序叫TEST,并选择DLL方式,见图2.1

 

2.1

 

n         步骤3:增加ATL对象类。在菜单 Insert/New ATL Object...(或者用鼠标右键在 ClassView 卡片中弹出菜单)并选择Object 分类,选中 Internet Exploer 项目。见图2.2

2.2

n         步骤4:填写COM类的名称。只要输入Short Name,其它自动生成。见图2.3

2.3

2.2实现IObjectWithSite的接口方法

n         步骤1:先定义几个成员变量:CComQIPtr mWebBrowser2,(需要加入#include "ExDisp.h"),用以保存浏览器组件的指针;DWORD mCookie,用以保存与浏览器的连接ID。见图2.4

变量声明

2.4(详见MyBho.h文件)

n         步骤2:IObjectWithSite有两个接口方法:SetSiteGetSite。我们只需重载 SetSite就行了。在ImyBho中增加函数声明SetSite函数。见图2.5

2.5

n         步骤3: 实现IDispatch接口方法。事件处理也就在IDispatch::Invoke中实现(各个事件的IDExDispID.h中定义)。 BHO可能会接收到很多事件,但我们只需要响应我们感兴趣的那一部分。首先在ImyBho中增加该函数的声明。见图2.6

2.6

n         步骤4: ImyBho添加RegisterEventHandlerBOOL  inAdvise)方法声明,实现向IE注册和注销事件。详见附录代码。

通过上面的步骤,一个基本的BHO对象框架已经建立起来了。下一节来我们将根据具体要实现的功能(Server发送注销Session命令)对代码主要功能作说明。

三,注销Session

3.1BHO注册为浏览器的事件处理器

   注册BHO的事件的工作主要在SetSite函数中来完成。首先保存浏览器指针到mWebBrowser2成员变量中去。然后调用RegisterEventHandler函数向浏览器注册为事件处理器。见图3.1

/************************************************************

 说明:SetSite(IUnknown *pUnkSite)IObjectWithSite接口的方法。

功能:1.保存浏览器组件指针,

       2.BHO向浏览器注册为事件处理器。

************************************************************/

STDMETHODIMP CMyBho::SetSite(IUnknown *pUnkSite){

         if (pUnkSite){

       //保存浏览器指针到mWebBrowser2成员变量中去。

           mWebBrowser2 = pUnkSite;

          if (mWebBrowser2){

//向浏览器注册为事件处理器。

           return RegisterEventHandler(TRUE);

           }

         }

         return E_FAIL;}

}

/**********************************************************

 说明:自定义函数,用以注册/注销BHO事件。

 功能:根据传入的参数TRUE/FALSE来向浏览器注册/注销BHO事件。

 **********************************************************/

STDMETHODIMP CMyBho::RegisterEventHandler(BOOL inAdvise)

{

         CComPtr spCP;

         // 得到浏览器的连接点

         CComQIPtr spCPC(mWebBrowser2);

         HRESULT hr = spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP);

         if (FAILED(hr)){

                   return hr;

         }

         if (inAdvise){

                   // 向浏览器注册事件。

                   hr = spCP->Advise(reinterpret_cast(this), &mCookie);

         }else{

               // 向浏览器注销事件。

                   spCP->Unadvise(mCookie);

         }

         return hr;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


3.1(详见MyBho.cpp文件)

3.2监听浏览器关闭事件,并向Server发送跳转指令

监听浏览器事件,全部在Invoke函数中来完成。当捕获了浏览器退出事件(DISPID_ONQUIT)时,首先取得页面的窗口名,判读是不是成功登陆页面。如果是,向Server LogOffAction发送一组数据,通知ServerBHO注销事件。然后退出IE。见图3.2

         case DISPID_ONQUIT:

                   {

                    //取得当前页面的标题。

                      BSTR lpHader = NULL;

                  mWebBrowser2->get_LocationName(&lpHader);

                 //如果是标题是“登录成功页面”的话,说明用户关闭的是已经登录的主页。

                      if (strstr( "登录成功页面", OLE2CA(lpHader))){

                  //需要跳转到ServerLogOutAction中去的URL

                             LPTSTR hostUrl = _T("http://localhost:8080/LogOff/logout.do");

                            //Server发送"action=BhoLogoff",提示是BHO注销事件。

LPTSTR postData = _T("action=BhoLogoff");

 

 

 

 

 

 

//取得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;

    //此处略去给参数赋值的代码,详见MyBho.cpp中的Invoke函数。

    ………………………………………………..

   //跳转函数,并向Server发送数据。

       mWebBrowser2->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);

}

//注销BHO事件处理器。  

RegisterEventHandler(FALSE);

break;

}

 

 

 

 

 

 

 

 

 


3.2(详见MyBho.cpp文件)

3.3关闭BHO注销页面

Server监听到BHO发来的注销命令时,Server注销当前用户的Session后,跳转到一个专门的BHO注销页面(正常情况下是注销退出到登陆页面)。当BHO检测到IE已经跳转到BHO注销页面时,就将窗口关闭。从而使用户对于注销过程可以忽视。见图3.3

case  DISPID_NAVIGATECOMPLETE2://监听页面跳转完毕事件

{//参数合法性检查

if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT)){

char * strurl;

 CComVariant varURL(*pDispParams->rgvarg[0].pvarVal);

 varURL.ChangeType(VT_BSTR);

strurl = OLE2A(varURL.bstrVal);

//如果发现当前的URLBHO注销页面,则关闭当前页面

if (strstr("http://localhost:8080/LogOff/BhoLogOut.jsp", strurl)){                        

       mWebBrowser2->Quit();

}

}

break;

}

 

 

 

 

 

 

 


3.3(详见MyBho.cpp文件)

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("explorer.exe"))) {

                      return FALSE;

             }

             _Module.Init(ObjectMap, hInstance, &LIBID_TESTLib);

             DisableThreadLibraryCalls(hInstance);

    }else if (dwReason == DLL_PROCESS_DETACH){

             _Module.Term();

    }

             return TRUE; // ok

}

 

 

 

 

 

 

 

 

 

 


3.4(详见TEST.cpp文件)

3.5向注册表中注册BHO组件

   为了向注册表中注册BHO组件,还需要在MyBho.rgs中加入下面的代码。见图3.5

HKLM{

    SOFTWARE{

              Microsoft{

                       Windows{

                                CurrentVersion{

                                          Explorer{

                                                   'Browser Helper Objects'{

                                                   {E5155767-23E5-4142-A63B-4DA81B196C36}}

                                          }

                                }

                       }

              }

     }

}

 

 

 

 

 

 

 

 


3.5(详见MyBho.rgs文件)

 

到此,一个简单的注销SeesionBHO插件开发完毕了,当然还要在根据具体情况,在Server端加以判断才行。详细代码,请参考附录。

四,打包发布

经过前面的工作,这个BHO可以打包成CAB格式发布到网站了。当然还要在CAB包中编写一个自动安装的脚步。当用户登录网站,就可以自动安装插件了。下面是详细步骤。

4.1 BHO打包和找到关联Dll文件

      首先,把BHO打包成Dll文件。在VCBuild菜单中选择 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 Studio/Common/Tools目录下)。使用它打开我们刚编译好的Dll文件,就可以看到和它关联的所有Dll文件。见图4.1

4.1

从图中可以看到,当前的Dll用到的VC库文件是OLE32.DLL ,OLEAUT32.DLL。然后我们在Windows/System32目录下找到这两个个文件,复制。然后和生成的test.dll放到一个文件夹。

4.2编写自动安装脚本inf文件

由于我们的CAB包要自动下载安装到用户的电脑上面,所有必须要编写一个inf安装脚本。关于inf自动安装脚本的说明,详见图4.2

固定格式

此处声明都有哪些文件。注意顺序,被调用的dll要放到前面。

1.      file值告诉ie到哪里去得到这个dll

2.      第二部分告诉声明支持的OS

3.      第三部分是CPU类型

4.      thiscab说明在当前的cab文件

 

DllCLSID。在VC中的rgs文件中可以找到。

是否需要注册

dll将要存到本地硬盘的位置,如果它的值是10,则将dll放到/Windows或者/WinNT下;如果是11,则放到/Windows/System或者 /WinNT/System32下;如果是空(就是没有值)则会放到/Windows或者/WinNT下的Downloaded Program Files目录下;  

  

4.2

 

4.3cabarc工具打包。

       下载此工具http://mydown.yesky.com/yule/meinv/179/418679.shtml

       把刚才的文件都拷贝到该工具的BIN目录下面。执行如下命令: cabarc –s 6144 N TEST.CAB oleaut32.dll ole32.dll test.dll TEST.inf 。执行完毕后,会在此目录下生成一个TEST.CAB包。这个压缩包就可以发布到网站了。当然现在这个包没有经过任何签名,在IE的默认安全策略下面是执行不了的,解决办法是:1.把放包的网站设置为信任站点。 2.花钱买一个证书,一年费用好像是5000多。当然我们是测试,所有采用第一种方式。

      编写一个HTML文件,插入以下代码<OBJECT ID="BhoTest"   CLASSID="CLSID: E5155767-23E5-4142-A63B-4DA81B196C36" CODEBASE="TEST.CAB">OBJECT> 然后把TEST.CAB放到网站目录下。运行见图4.3

4.3

由于没有获取认证,所以弹出警告框。点击安装后,我们的文件就被复制到了Windows/Systeme32的目录下面了。并且已经注册。再重启IE,我们的BHO就开始运行了。

:如需要删除BHO。请用 regsvr32 –u “文件路径 + 文件名来注销。然后就可以删除掉了。

 

你可能感兴趣的:(浏览器,dll,server,microsoft,session,windows)