`
唐风汉月
  • 浏览: 52565 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

VC++开发Activex控件以及签名发布

阅读更多

前言
      本人不懂C++,当前由于要做一个打印控件,使用Activex插件技术,所以在网络上搜索了相关技术文档,今天有空,遂将自己的当前学到的一些关于Activex技术整理之,进而和朋友们分享之。
一、 开发环境
开发工具:Visual Studio 2008
开发语言:Visual C++

测试工具:IE 7+
二、 创建MFC ActiveX项目
1、 打开VS2008新建MFC项目。这里我们取名为“PrintUtil”。

 

 
2、 输入项目名称为“PrintUtil”和项目位置。点击“确定”按钮,打开向导对话框。 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 
3、 选择“控件设置”选项卡,具体设置可参考上图。其它选项卡为默认设置。最后点击“完成”按钮保存设置。

 

三、 添加控件方法
VC2005会为我们自动创建好MFC ActiveX程序框架,我们只要给该ActiveX控件添加方法即可。现在我们给控件添加一个“AddFun”方法,这个方法是将两个数相加并返回结果。
1、 点击“视图”,打开“类视图”窗口。 


 
  
2、 展开“PrintUtilLib”项,选中“_DPrintUtil”项。点击鼠标右键,选择“添加”下的“添加方法”。 


 
 
3、 打开添加方法向导窗口。因为我们是添加一个加法方法,所以我们设置的返回类型为LONG型,方法名设为AddFun,添加两个LONG类型参数Add1,Add2。

4、   其它为默认设置,点击“完成”按钮完成添加方法。接下来我们打开“解决方案资源管理器”打开“PrintUtilCtrl.cpp”文件。



5、 打开代码视图,我们会发现VC2005已经为我们添加了一个“AddFun”方法,我们在方法内添加“return Add1 + Add2;”语句。

 

四、 MFC Activex 安全问题
1、在默认环境下,编译的MFC Activex控件,只能在本地代码中运行,即在http://localhost/xxx/xxx.htm中执行,而在http://127.0.0.1/xxx/xxx.htm中提示无相关属性,需要设置其初始化和脚本运行的安全性
ActiveX在远程IE页面上执行,需要实现安全接口。
在ATL写的ActiveX中,用IObjectSafety。
http://support.microsoft.com/kb/168371/en-us
在MFC写的ActiveX中,直接修改注册表。
http://support.microsoft.com/kb/161873/en-us
mfc实现的ocx,要在app实现文件中包括两个文件:
在PrintUtil.h文件中实现以下方法:

// PrintUtil.cpp : CPrintUtilApp 和DLL 注册的实现。 
#include "stdafx.h" 
#include "PrintUtil.h" 
#include <objsafe.h> 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 


CPrintUtilApp theApp; 

const GUID CDECL BASED_CODE _tlid = 
{ 0x3C8F86CA, 0x6470, 0x4B7C, { 0xB2, 0x76, 0x3B, 0xEB, 0xF, 0xB0, 0x1B, 0x4E } }; 
const WORD _wVerMajor = 1; 
const WORD _wVerMinor = 0; 



// CPrintUtilApp::InitInstance - DLL 初始化 

BOOL CPrintUtilApp::InitInstance() 
{ 
BOOL bInit = COleControlModule::InitInstance(); 

if (bInit) 
{ 
// TODO: 在此添加您自己的模块初始化代码。 
} 

return bInit; 
} 



// CPrintUtilApp::ExitInstance - DLL 终止 

int CPrintUtilApp::ExitInstance() 
{ 
// TODO: 在此添加您自己的模块终止代码。 

return COleControlModule::ExitInstance(); 
} 

// 创建组件种类   
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription) 
{    
    ICatRegister* pcr = NULL ;    
    HRESULT hr = S_OK ;    
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);    
    if (FAILED(hr)) return hr;    
    // Make sure the HKCR\Component Categories\{..catid...}    
    // key is registered.    
    CATEGORYINFO catinfo;    
    catinfo.catid = catid;    
    catinfo.lcid = 0x0409 ; // english    
    // Make sure the provided description is not too long.    
    // Only copy the first 127 characters if it is.    
    int len = wcslen(catDescription);    
    if (len>127) len = 127;    
    wcsncpy(catinfo.szDescription, catDescription, len);    
    // Make sure the description is null terminated.    
    catinfo.szDescription[len] = '\0';    
    hr = pcr->RegisterCategories(1, &catinfo);    
    pcr->Release();    
    return hr;    
}  

// 注册组件种类   
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid) 
{    
    // Register your component categories information.    
    ICatRegister* pcr = NULL ;    
    HRESULT hr = S_OK ;    
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);    
    if (SUCCEEDED(hr)) {    
      // Register this category as being "implemented" by the class.    
      CATID rgcatid[1];    
      rgcatid[0] = catid;    
      hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);    
    }    
    if (pcr != NULL) pcr->Release();    
    return hr;    
}   

// 卸载组件种类   
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid) 
{    
    ICatRegister* pcr = NULL ;    
    HRESULT hr = S_OK ;    
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,    
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);    
    if (SUCCEEDED(hr)) {    
      // Unregister this category as being "implemented" by the class.    
      CATID rgcatid[1] ;    
      rgcatid[0] = catid;    
      hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);    
    }    
    if (pcr != NULL) pcr->Release();    
    return hr;    
}    


// DllRegisterServer - 将项添加到系统注册表 
STDAPI DllRegisterServer(void) 
{    
    HRESULT hr;    
    AFX_MANAGE_STATE(_afxModuleAddrThis);    
    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))    
        return ResultFromScode(SELFREG_E_TYPELIB);    
    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))    
        return ResultFromScode(SELFREG_E_CLASS);    
    // 标记控件初始化安全.    
    // 创建初始化安全组件种类   
    hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");    
    if (FAILED(hr)) return hr;    
    // 注册初始化安全   
    hr = RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForInitializing);    
    if (FAILED(hr)) return hr;    
    // 标记控件脚本安全   
    // 创建脚本安全组件种类   
    hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");    
    if (FAILED(hr)) return hr;    
    // 注册脚本安全组件种类   
    hr = RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    
    if (FAILED(hr)) return hr;    
    return NOERROR;    
}    

// DllUnregisterServer - Removes entries from the system registry    
STDAPI DllUnregisterServer(void) 
{    
    HRESULT hr;    
    AFX_MANAGE_STATE(_afxModuleAddrThis);    
    if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))    
        return ResultFromScode(SELFREG_E_TYPELIB);    
    if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))    
        return ResultFromScode(SELFREG_E_CLASS);    
    // 删除控件初始化安全入口.    
    hr=UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForInitializing);    
    if (FAILED(hr)) return hr;    
    // 删除控件脚本安全入口   
    hr=UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    
    if (FAILED(hr)) return hr;    
    return NOERROR;    
}  

  

现在控件就可以在自注册时就注册为安全控件了。
2、设置项目属性 将配置类型设置成静态库(.lib)

3、最后生成项目,ocx控件就产生了。
五、 ActiveX发布步骤
在这里简单说明下,打包activeX需要制作证书,具体用到makecert 、cert2spc 、signtool 这三个VS提供的工具,工具在VS文件夹里面,以下制作过程需要在工具所在的文件夹下完成!
1、单击"开始"-->"运行(R)"-->输入"cmd"-->回车-->进入到操作的控件所在的目录(需要将上面所说的工具,和ocx控件放到一个文件夹下);


2、创建PVK文件(私人密匙文件),在命令行中输入" makecert -sk PrintUtil PrintUtil.pvk -n CN=XXXXXXX公司",然后回车;
sk-表示主题的密钥容器位置,ss-主题的证书存储名称, n-证书颁发对象,r-证书存储位置;

3、创建CER文件(公司证书),在命令行中输入" makecert -sk PrintUtil.pvk PrintUtil.cer ",然后回车,如图所示,若出现"Successed"提示,则会在C:\ PrintUtil目录下生成PrintUtil.cer文件;
sk-表示主题的密钥容器位置,is-颁发者的证书存储名称, n-证书颁发对象,ic-颁发者的证书存储位置,-$-授权范围(用于代码签名);

 
4、创建SPC测试软件出版商证明书,在命令行中输入" cert2spc PrintUtil.cer PrintUtil.spc ",然后回车;

5、创建INF文件,用记录本编辑以下信息:

[version] 
signature="$CHINA$" 
AdvancedINF=1.0 

[Add.Code] 
PrintUtil.ocx=PrintUtil.ocx 

[PrintUtil.ocx] 
file=thiscab 
clsid={ 1BABEDC3-3936-4850-B79B-2417E28A5655 } 
FileVersion=1,0,0,0 
RegisterServer=yes 
DestDir=11 

 

6、创建CAB文件,在命令行中输入" cabarc -s 6144 n PrintUtil.cab PrintUtil.ocx PrintUtil.inf ",-s 选项表示在压缩文件中保留用于代码签名的空间,n命令指定希望创建 CAB 文件,然后回车;

7、使用Code Signing Wizard签署一个CAB文件,首先双击运行工具集里面的signcode.exe(或在命令行里直接输入“signcode”后回车),系统会弹出如图所示的数字签名向导;

8、单击"下一步(N)"按钮,选择要进行数字签名的且已做成CAB包的文件PrintUtil.cab文件;

9、选择好CAB包后单击"下一步(N)"按钮,在选择想要的签名类型里选择"自定义(C)"并单击"下一步(N)"按钮;

10、点击“从文件选择”签名证书 ( 公钥文件 ),如: PrintUtil.cer :

11、在图20中单击“下一步(N)”按钮来到下图,然后在图里选择“CSP中的私钥(K)”。

12、在上图中单击“下一步(N)”按钮,然后在下图中的散列算法中选择“shal”,并单击“下一步(N)”按钮。

13、在“证书路径中的证书”中选择“证书路径中的所有证书,包括根证书(C)”,在“其它证书(可选)”中选择“包括在以下PKCS #7 证书(.p7b)文件中的证书(P):”,并单击“浏览(R)…”按钮选择PrintUtil.spc文件,选择完后单击“下一步(N)”按钮:

14、接下来在弹出的“数据描述”窗口中输入公司的名称和网址并单击“下一步(N)”按:

15、现大部份工作都已完成,在接下来的一步当中是可选的操作,其作用只是为CAB加入时间戳,此步骤完全可以不做。

VeriSign:  http://timestamp.verisign.com/scripts/timstamp.dll
Comodo:  http://timestamp.comodoca.com/authenticode
GeoTrust/TrustCenter: http://www.trustcenter.de/codesigning/timestamp
16、完成

六、 运行
编写jsp页面,test.jsp 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 
<% 
String path = request.getContextPath(); 
String basePath = request.getScheme() + "://" 
+ request.getServerName() + ":" + request.getServerPort() 
+ path + "/"; 
%> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
<head> 
<base href="<%=basePath%>"> 

<title>My JSP 'index.jsp' starting page</title> 
<meta http-equiv="pragma" content="no-cache"> 
<meta http-equiv="cache-control" content="no-cache"> 
<meta http-equiv="expires" content="0"> 
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 
<meta http-equiv="description" content="This is my page"> 
<object id="printUtil" 
classid="clsid:1BABEDC3-3936-4850-B79B-2417E28A5655" 
codebase="<%=basePath%>/PrintUtil.cab#version=1,0,0,0"></object> 
<script type="text/javascript"> 
	function add(arg1,args) { 
		try { 
			var v = printUtil.AddFun(arg1,args); 
			alert(v); 
		} catch (e) { 
			alert(e.message) 
		} 
	} 
	add(1,2); 
</script> 
</head> 
<body> 
</body> 
</html>

  
运行结果:



 
 好了,今天就写到这里了,如果朋友们有什么疑问或者更好的建议和意见,请Email Me。

 

Email:df.jxnu@gmail.com

 

本文所用到的工具见附件:

 

转载请声明本文链接

  • 大小: 29.9 KB
  • 大小: 26.9 KB
  • 大小: 27 KB
  • 大小: 18.5 KB
  • 大小: 6.7 KB
  • 大小: 6 KB
  • 大小: 82.1 KB
  • 大小: 9.4 KB
  • 大小: 27 KB
  • 大小: 18.4 KB
  • 大小: 13 KB
  • 大小: 8.8 KB
  • 大小: 13.7 KB
  • 大小: 17.9 KB
  • 大小: 32.9 KB
  • 大小: 25.3 KB
  • 大小: 7.6 KB
  • 大小: 7.7 KB
  • 大小: 8.6 KB
  • 大小: 9.6 KB
  • 大小: 10.8 KB
  • 大小: 18.4 KB
  • 大小: 21 KB
  • 大小: 17.2 KB
  • 大小: 26.9 KB
  • 大小: 13.2 KB
  • 大小: 20 KB
  • 大小: 14.7 KB
  • 大小: 12.9 KB
  • 大小: 19.3 KB
  • 大小: 10.2 KB
  • 大小: 31.7 KB
  • 大小: 20.6 KB
  • 大小: 35.3 KB
  • 大小: 12.5 KB
  • 大小: 21.3 KB
  • 大小: 21.1 KB
  • 大小: 36.6 KB
  • 大小: 14.5 KB
  • 大小: 23.3 KB
  • 大小: 7.8 KB
  • 大小: 6.4 KB
  • 大小: 6.2 KB
分享到:
评论
5 楼 webiis2008 2014-11-19  
尝试了很久用自己做的证书被浏览器拦截了。最后购买沃通的代码签名证书才能发布。
4 楼 freeubuntu-it 2012-10-16  
我按照demo做的时候,出现提示对话框
“是否允许运行软件,如ActiveX控件和插件”~
3 楼 jwsong2001ok 2012-10-11  
我照着做的demo运行时,IE中就会提示,“在此页上的ActiveX控件和本页上的其他部分的交互可能不安全,你想允许这种交互吗?”,这是正常的吗?怎么把这个给去掉?
2 楼 唐风汉月 2010-12-27  
kidfang 写道
祝贺!VS2008的,客户端不要装DOTNET框架吧?

不需要,C++语言实现的,这里和dotnet无关
1 楼 kidfang 2010-12-27  
祝贺!VS2008的,客户端不要装DOTNET框架吧?

相关推荐

    VC++开发Activex控件以及签名发布.pdf

    VC++开发Activex控件以及签名发布.pdf ACTIVEX编程开发总结

    VC 开发Activex控件以及签名发布技术

    "VC 开发Activex控件以及签名发布技术" 一、 Activex 控件的基本概念 Activex 控件是微软公司开发的一种控件技术,可以在多种平台上运行,包括 Windows、Macintosh 和 Unix 等。Activex 控件可以嵌入到网页中,...

    VC++插件与ActiveX技术

    通过学习这些资料,开发者不仅可以掌握如何在VC++环境中开发ActiveX控件和插件,还能了解到如何将这些技术应用到实际项目中,提升软件开发的效率和质量。无论是对初学者还是有经验的开发者来说,这都是一份宝贵的...

    vc++ ActiveX打包与发布用到的工具cert2spc.exe,makecert.exe,signcode.exe

    在开发和分发VC++ ActiveX控件时,安全性和信任是至关重要的因素。为了确保用户能够安全地在他们的应用程序中使用这些控件,开发者需要对它们进行签名,以证明其来源和完整性。这里提到的三个工具——`cert2spc.exe`...

    vc开发ocx控件

    从给定的文件信息来看,本文主要讲述了如何使用VC2005开发MFC ActiveX控件以及如何将其发布到.net网站上。以下将详细说明知识点: 1. MFC ActiveX控件简介 ActiveX控件是基于COM技术的一种组件模型,由Microsoft...

    54 款很不错的VB ActiveX控件

    其次,随着.NET Framework和Windows Forms、WPF等现代开发平台的出现,ActiveX控件的使用逐渐减少。最后,ActiveX控件通常只适用于Windows环境,对跨平台开发支持不足。 总的来说,"54款很不错的VB ActiveX控件"为...

    activex初学者资料整理

    4. **使用VS2008C#开发ActiveX控件**: Visual Studio 2008提供了开发ActiveX控件的支持,通过.NET Framework,开发者可以用C#创建COM兼容的控件。控件需设置 ComVisible 属性为 true,并导出所需接口。开发完成后...

    使用Cab包部署ActiveX控件.docx

    总的来说,利用Cab包部署ActiveX控件涉及多个步骤,包括下载工具、编写INF文件、创建CAB、签名以及发布。这个过程虽然有些复杂,但却是确保ActiveX控件安全、可靠分发的重要方法。随着技术的发展,现代浏览器逐渐弃...

    Active控件打包发布

    ActiveX控件通常用Visual Basic、VC++等编程语言开发,并且可以在Internet Explorer浏览器中运行。然而,为了让这些控件能在用户的计算机上安全地运行,开发者需要对它们进行签名和打包,确保其来源可信且无恶意代码...

    ActiveX

    2. **ActiveX控件开发**:学习如何使用Visual Basic、VC++或Delphi等编程语言创建ActiveX控件,并了解控件属性、方法和事件的定义。 3. **注册和使用控件**:学习如何在Windows系统中注册ActiveX控件,并在应用程序...

    ActiveX.rar

    在ActiveX开发中,开发者通常会使用Visual Basic、VC++或者VBScript等编程语言,创建一个具有特定功能的ActiveX控件。这个控件可以是一个自定义的用户界面元素,如按钮、文本框,或者是执行特定任务的逻辑模块,如...

    VC.ActiveX.controls.code.ATL.rar_ ActiveX ATL_atl ACTIVEX dll_at

    因此,在设计和部署ActiveX控件时,必须考虑安全因素,如限制控件的权限,使用代码签名等。 9. **替代技术**:随着Web技术的发展,ActiveX已被更现代的Web标准如HTML5、JavaScript和Web Components所取代。然而,在...

    ActiveX Web开发指南3

    1. **ActiveX组件的创建**:开发者可以使用Visual Basic、VC++或Delphi等编程语言创建ActiveX控件。控件的创建过程涉及定义接口、实现类工厂、注册组件等步骤,确保控件能在Internet Explorer中正确识别和使用。 2....

    VisualC++.ActiveX VisualC++.ActiveX

    7. **调试与部署**:提供ActiveX控件的调试技巧和发布策略。 8. **案例分析**:通过实际的开发案例,展示如何使用Visual C++和ActiveX技术构建复杂应用。 通过学习和实践,开发者可以掌握在Visual C++中利用ActiveX...

    VC++6.0技术内幕

    此外,还应该会介绍如何使用ActiveX控件的安全特性,例如数字签名和控件的授权机制,来确保控件在不同环境下安全运行。 以上就是《VC++6.0技术内幕》这本书籍中可能包含的知识点。虽然这里没有直接引用图书的内容,...

    WEB载入OCX控件教程(VC的OCX教程完整版)

    在制作OCX控件时,需要使用VS 2008创建一个新的工程,选择“MFC ActiveX控件”。在类视图中添加接口,注意接口的参数类型要与JS一致,数字型的参数用SHORT,字符串型的参数用BSTR。如果不一致,JS在调用接口时会提示...

    activeX.zip

    - **代码签名**:为了安全,ActiveX控件可能需要数字签名,以确保其来源可信且未被篡改。 - **兼容性**:确保控件与目标系统的版本兼容,包括操作系统的版本、VC++运行库等。 - **权限设置**:由于ActiveX控件可能...

    PowerTCP_SSL_ActiveX_Trial.zip

    在VC++开发环境中,使用PowerTCP SSL ActiveX控件可以轻松地为您的应用程序添加SSL支持。ActiveX是一种组件对象模型(COM),在Windows平台上广泛应用,它允许开发者在不同程序间共享代码,提高开发效率。PowerTCP ...

    Foxit PDF SDK ActiveX Std 5.4

    Foxit PDF SDK ActiveX Std 5.4 是一套专门用于开发PDF相关应用的软件开发工具包,它提供了ActiveX控件,使得开发人员能够在各种基于Windows的应用程序中集成PDF功能,如创建、编辑、阅读、打印PDF文档等。...

Global site tag (gtag.js) - Google Analytics