VB6开发ActiveX插件 JS调用 实现安全接口

时间:2022-06-12 21:01:35

最近一直在做插件方面的工作,总结一下开发过程中的心得,也分享给大家,主要围绕以下内容展开

  1.ActiveX插件开发

  2.JS调用ActiveX

  3.ActiveX实现安全接口

本文主要是讲vb6制作插件,由于.net环境开发下的插件客户端必须安装.netFramework相关系列版本,无疑对用户来说不太方便,故采用vb来开发插件

本例中开发的插件主要目的是让JS调用其方法,与此同时实现插件的安全接口(这样安装一次之后浏览器就不会阻止了,简单的就可以这么理解)

  . 建立ActiveX

  1.打开VB6.o,新建ActiveX控件工程,保存工程名为Project,可默认使用当前的UserControl1用户控件,在UserControl1用户控件中编写如下代码,并保存工程和控件

Public   Function  msg(ByVal str  As   String )
MsgBox   " 您好: "   &  str  &   "   插件测试成功! " End  
Function

   2.实现安全接口,这样更加安全

    从VB CD-ROM取得OLE 自动化类库的制作工具。将VB安装光盘中\Common\Tools\VB\Unsupprt\Typlib\目录下所有内容一并拷贝到Project项目文件夹中,然后将下列内容拷贝到记事本中,将记事本命名为Objsafe.odl  

    [
           uuid(C67830E0
- D11D - 11cf - BD80 - 00AA00575603),
           helpstring(
" VB IObjectSafety Interface " ),
           version(
1.0 )
       ]
       library IObjectSafetyTLB
       {
           importlib(
" stdole2.tlb " );
           [
               uuid(CB5BDC81
- 93C1 - 11cf - 8F20 - 00805F2CD064),
               helpstring(
" IObjectSafety Interface " ),
               odl
           ]
           interface IObjectSafety:IUnknown {
               [helpstring(
" GetInterfaceSafetyOptions " )]
               HRESULT GetInterfaceSafetyOptions(
                         [in]   
long    riid,
                         [in]   
long   * pdwSupportedOptions,
                         [in]   
long   * pdwEnabledOptions);

               [helpstring(
" SetInterfaceSafetyOptions " )]
               HRESULT SetInterfaceSafetyOptions(
                         [in]   
long    riid,
                         [in]   
long    dwOptionsSetMask,
                         [in]   
long    dwEnabledOptions);
            }
        } 

    3创建tlb文件,打开命令提示符并切换至Project项目文件夹下,运行下面的命令

      MKTYPLIB objsafe.odl /tlb objsafe.tlb

    4添加引用

    打开菜单“工程->引用”,点“浏览”,找到刚刚建立的Objsafe.tlb,把它加入到引用中

    注意:只有VB6开发ActiveX插件 JS调用 实现安全接口VB IObjectSafety Interface打上勾才算引用成功

     5.选择启动项,工程->属性->启动对象,选择Sub Main不然会引起“automation服务器不能创建对象的错误

   6.右键项目,"添加"->"添加模块",新添加一个模块并命名为basSafeCtl,在该模块中填入以下代码

Option   Explicit

      
Public   Const  IID_IDispatch  =   " {00020400-0000-0000-C000-000000000046} "
      
Public   Const  IID_IPersistStorage  =  _
        
" {0000010A-0000-0000-C000-000000000046} "
      
Public   Const  IID_IPersistStream  =  _
        
" {00000109-0000-0000-C000-000000000046} "
      
Public   Const  IID_IPersistPropertyBag  =  _
        
" {37D84F60-42CB-11CE-8135-00AA004BB851} "

      
Public   Const  INTERFACESAFE_FOR_UNTRUSTED_CALLER  =   & H1
      
Public   Const  INTERFACESAFE_FOR_UNTRUSTED_DATA  =   & H2
      
Public   Const  E_NOINTERFACE  =   & H80004002
      
Public   Const  E_FAIL  =   & H80004005
      
Public   Const  MAX_GUIDLEN  =   40

      
Public  Declare  Sub  CopyMemory Lib  " kernel32 "  Alias  " RtlMoveMemory "  _
         (pDest 
As  Any, pSource  As  Any, ByVal ByteLen  As   Long )
      
Public  Declare  Function  StringFromGUID2 Lib  " ole32.dll "  (rguid  As  _
         Any, ByVal lpstrClsId 
As   Long , ByVal cbMax  As   Integer As   Long

      
Public  Type udtGUID
          Data1 
As   Long
          Data2 
As   Integer
          Data3 
As   Integer
          Data4(
7 As   Byte
      
End  Type

      
Public  m_fSafeForScripting  As   Boolean
      
Public  m_fSafeForInitializing  As   Boolean

      
Sub  Main()
          m_fSafeForScripting 
=   True
          m_fSafeForInitializing 
=   True
      
End Sub

   7.向UserControl1用户控件中追加如下代码,实现安全接口

    首先在用户控件代码区顶部加入

  
  
  
Implements IObjectSafety

    之后在代码底部添加如下代码

Private   Sub  IObjectSafety_GetInterfaceSafetyOptions(ByVal riid  As  _
      
Long , pdwSupportedOptions  As   Long , pdwEnabledOptions  As   Long )

          
Dim  Rc       As   Long
          
Dim  rClsId   As  udtGUID
          
Dim  IID      As   String
          
Dim  bIID()   As   Byte

          pdwSupportedOptions 
=  INTERFACESAFE_FOR_UNTRUSTED_CALLER  Or  _
                                INTERFACESAFE_FOR_UNTRUSTED_DATA

          
If  (riid  <>   0 Then
              CopyMemory rClsId, ByVal riid, 
Len (rClsId)
 
              bIID 
=   String $(MAX_GUIDLEN,  0 )
              Rc 
=  StringFromGUID2(rClsId, VarPtr(bIID( 0 )), MAX_GUIDLEN)
              Rc 
=   InStr ( 1 , bIID, vbNullChar)  -   1
              IID 
=   Left $( UCase (bIID), Rc)

              
Select   Case  IID
                  
Case  IID_IDispatch
                      pdwEnabledOptions 
=  IIf(m_fSafeForScripting, _
                    INTERFACESAFE_FOR_UNTRUSTED_CALLER, 
0 )
                      
Exit   Sub
                  
Case  IID_IPersistStorage, IID_IPersistStream, _
                     IID_IPersistPropertyBag
                      pdwEnabledOptions 
=  IIf(m_fSafeForInitializing, _
                    INTERFACESAFE_FOR_UNTRUSTED_DATA, 
0 )
                      
Exit   Sub
                  
Case   Else
                      Err.Raise E_NOINTERFACE
                      
Exit   Sub
              
End   Select
          
End   If
      
End Sub

      
Private   Sub  IObjectSafety_SetInterfaceSafetyOptions(ByVal riid  As  _
      
Long , ByVal dwOptionsSetMask  As   Long , ByVal dwEnabledOptions  As   Long )
          
Dim  Rc           As   Long
          
Dim  rClsId       As  udtGUID
          
Dim  IID          As   String
          
Dim  bIID()       As   Byte

          
If  (riid  <>   0 Then
              CopyMemory rClsId, ByVal riid, 
Len (rClsId)

              bIID 
=   String $(MAX_GUIDLEN,  0 )
              Rc 
=  StringFromGUID2(rClsId, VarPtr(bIID( 0 )), MAX_GUIDLEN)
              Rc 
=   InStr ( 1 , bIID, vbNullChar)  -   1
              IID 
=   Left $( UCase (bIID), Rc)

              
Select   Case  IID
                  
Case  IID_IDispatch
                      
If  ((dwEnabledOptions  And  dwOptionsSetMask)  <>  _
                   INTERFACESAFE_FOR_UNTRUSTED_CALLER) 
Then
                          Err.Raise E_FAIL
                          
Exit   Sub
                      
Else
                          
If   Not  m_fSafeForScripting  Then
                              Err.Raise E_FAIL
                          
End   If
                          
Exit   Sub
                      
End   If

                  
Case  IID_IPersistStorage, IID_IPersistStream, _
                IID_IPersistPropertyBag
                      
If  ((dwEnabledOptions  And  dwOptionsSetMask)  <>  _
                    INTERFACESAFE_FOR_UNTRUSTED_DATA) 
Then
                          Err.Raise E_FAIL
                          
Exit   Sub
                      
Else
                          
If   Not  m_fSafeForInitializing  Then
                              Err.Raise E_FAIL
                          
End   If
                          
Exit   Sub
                      
End   If

                  
Case   Else
                      Err.Raise E_NOINTERFACE
                      
Exit   Sub
              
End   Select
          
End   If
      
End Sub

  8.运行工程,出现的插件网页中查看网页源代码,得到如下html代码

< HTML >< BODY >< OBJECT  classid ="clsid:E4596214-B87A-4238-B19A-318767FBD9A5" >
</ OBJECT ></ BODY ></ HTML >

 

   9.生成OCX

    vb6.0中"文件"->"生成Project.ocx",生成ocx之后运行命令提示符注册该插件,打开命令提示符并切换至Project.ocx所在目录,运行如下命令

regsvr32 Project.ocx

  . JS调用ActiveX方法

    新建如下网页测试,其中有两种调用ActiveX方法的方法 

< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head  runat ="server" >
    
< title > 无标题页 </ title >

    
< script  type ="text/javascript" >    
    
            
function  showMsgByActiveXobject(){  
                        
var  ocx = new  ActiveXObject( ' Project.UserControl1 ' );    
                            ocx.msg(
" zhang " );                 
                                      }  
                                                
            
function  showMsgByObject(){ 
                        
var  abc = document.getElementById( " activeX " ); 
                            abc.msg(
" Li " );      
                                    }   
    
</ script >

    
< object  id ="activeX"  classid ="clsid:E4596214-B87A-4238-B19A-318767FBD9A5" >
    
</ object >
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
        
< div >
            
< input  type ="button"  value ="测试1"  onclick ="showMsgByActiveXobject()"   />
            
< input  type ="button"  value ="测试2"  onclick ="showMsgByObject()"   />
        
</ div >
    
</ form >
</ body >
</ html >