竹子_

stay hungry, stay fool
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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

Posted on 2011-05-25 16:10  竹子_  阅读(3836)  评论(0编辑  收藏  举报

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

  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,把它加入到引用中

    注意:只有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 IntegerAs Long

      
Public Type udtGUID
          Data1 
As Long
          Data2 
As Integer
          Data3 
As Integer
          Data4(
7As 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 <> 0Then
              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 <> 0Then
              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>