一 使控件实现 IObjectSafety 接口
1. 从 Visual Basic 6.0 光盘获取 OLE 自动化类型库生成器。 要这样做, 将所有四个文件从 "Common"Tools"VB"Unsupprt"Typlib" 文件夹复制到项目文件夹。 注意 : VIsual Basic 5.0 中 "VB5.0"Tools"Unsupprt"Typlib" 文件夹中复制所有文件。
2. 将以下文本复制到记事本, 并作为 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. 创建可保存所有文件, 本示例中创建新文件夹。
4. 从 Visual Basic 6.0 光盘获取 OLE 自动化类型库生成器。 要这样做, 将所有四个文件从"Common"Tools"VB"Unsupprt"Typlib" 文件夹复制到项目文件夹。 注意 : VIsual Basic 6.0 中 "VB6.0"Tools"Unsupprt"Typlib" 文件夹中复制所有文件。
3. 将以下文本复制到记事本, 并作为 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);
}}
4. 在命令提示符处, 使用 CD < 路径 > 命令移到项目文件夹, 然后键入以下命令以生成 .tlb 文件:
MKTYPLIB objsafe.odl /tlb objsafe.tlb
5. 从vb中新建ActiveX控件项目
6. 在 项目 菜单上, 单击 引用 , 浏览并添加 Objsafe.tlb, 它前面创建。
7. 向使用以下代码, 项目添加一个新模块并命名模块 basSafeCtl:
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
8.从 ProjectProperties@@, Startup 对象更改到要执行上述 SubMain SubMain 。 使用 m_fSafeForScripting 和 m_fSafeForInitializing 变量来指定安全执行脚本和/或初始化变量的值。
9.打开控件的代码窗口。 将下列行的代码添加到声明部分 (OptionExplicit 后或作为第):Implements IObjectSafety
10.新建一个模块复制下面两个过程到模块
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
11在 文件 菜单上, 保存您的项目和文件。 生成 OCX 文件从项目。 现在您控件实现 IObjectSafety 接口。
到此为止你已实现了一个标记为安全控件的ActiveX控件,你可以试试没有实现IObjectSafety 接口的控件的差别。
二.为控件加入数字签名,要加入数字签名你需要一下工具:
1使用makecert.exe创建私钥和证书
格式:makecert –sv YourPrivateName.pvk -ss Yourname –n “CN-YourName” YourCerName.cer执行命令将生产两个文件私钥YourPrivateName.pvk和证书:YourCerName.cer。
2使用signcode.exe将证书附件到ActiveX控件中(如果你在网页中是控件打包成cab,你也可以直接将证书附件到安装包上),运行后会有一个可视化的界面让你选择要控件和证书和私钥。
这样就完成了数字签名。
三在网页中加入ActiveX控件
<OBJECT
CLASSID="CLSID:DEE4306A-8D4A-4070-B1E6-EB08516101C0"
CODEBASE="YourActiveX.ocx#version=1,0,0,0" id="ScNO" name ="ScNO" height="15px" width="25px">
</OBJECT>
4306A-8D4A-4070-B1E6-EB08516101C0"
CODEBASE="YourActiveX.ocx#version=1,0,0,0" id="ScNO" name ="ScNO" height="15px" width="25px">
</OBJECT>
DEE4306A-8D4A-4070-B1E6-EB08516101C0为你控件在注册表中的CLSID值:当你用vb编译是自动注册到注册表中了你可以HKEY_CLASSES_ROOT查找,CODEBASE放的是你要被客户下载的控件路径和版本,当客户端的控件版本和这个不同是就会让客户安装。
调用控件中的方法:
<script language="javascript" type="text/javascript">
function GetDeriveID()
{
try
{
var Ctrl=document.getElementById ("ScNO");
if(Ctrl!=null)
{
var Msg=Ctrl.GetYourFun();
alert("调用成功");
}
else
{
alert("调用失败");
}
</script>
到现在为止你已可以发布你的网页了让在客户端试试会不会自动安装,如果没有客户端没有限制那么就能自动安装。如果万一不能自动安装你还可以写个程序让客户下载安装,我是写了一个批处理程序,来注册控件的。很简单:
注册:
@echo off
"regsvr32" " YourActiveX.ocx"
取消注册:
@echo off
"regsvr32" "-u" "SMCActX.ocx"
大家如果在开发中要用户ActiveX控件不妨参考一下,可省去不少弯路。