﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>学习日记 &#187; activex</title>
	<atom:link href="https://www.softwareace.cn/?cat=82&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://www.softwareace.cn</link>
	<description>时刻想着为自己的产品多做一些对他好的事情</description>
	<lastBuildDate>Fri, 20 Mar 2026 06:58:28 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>C++注册,卸载OCX控件,以及判断是否注册</title>
		<link>https://www.softwareace.cn/?p=574</link>
		<comments>https://www.softwareace.cn/?p=574#comments</comments>
		<pubDate>Tue, 17 Sep 2013 06:29:20 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[activex]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=574</guid>
		<description><![CDATA[[crayon-69fbc489eb3e8007425384/] &#160;]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">方法一＿/STRONG&gt;在dos或Windows命令行下运行：regsvr32 ocxname.ocx 注册

示例＿BR&gt;regsvr32 netshare.ocx     //注册netshare.ocx控件
regsvr32 /u netshare.ocx //解除netshare.ocx控件的注冿BR&gt;
如果netshare.ocx文件不在system目录时，还必须在文件名前加上完整的路径。除了regsvr32应用程序之外，Microsoft在它 皿web 站点上还提供了一个称为regclean.exe 的程序，可以检查注册表并去掉丢失的组件在注册表中的条目。regclean.exe 除了可以删除 “悬挂‿的条目，它还提供一个“undo‿文件帮助恢复错误的删除〿BR&gt;
甿regsvr32.exe 注册 activeX 控件虽然简单，但需要用户手工进行注册，在不用时还需手工解除注册〿BR&gt;
方法二：甿install shield，在里面逿“self-registered”，安装程序将自动注册；

方法三：api 函数注册
此方法的设计思路是：先将 activeX 控件载入内存，然后验证其有效性，最后直接在内存地址中执行其注册函数(DllRegisterServer〿 DllUnregisterServer)〿BR&gt;其编程方法是＿BR&gt;
1、使用Windows api 函数Loadlibrary 载入activeX 控件＿BR&gt;2、使用GetProcAddress 函数获取activeX 控件中注册函数DllRegisterServer(注销函数丿 DllUnregisterServer)指针＿BR&gt;3、使用CallwindowProc 函数执行已载入内存的activeX 控件注册函数(DllRegisterServer〿DllUnregisterServer)〿BR&gt;
示例＿BR&gt;
typedef int (callback* myfunction)(void);
myfunction   myfunction = null;
hinstance handle = null ;
handle = LoadLibrary("trdragdroptreectrl.ocx");

if( handle != null )
{
myfunction = GetProcAddress(handle, "DllRegisterServer");
if( myfunction != null )
{
myfunction();
}
}
方法四：代码调用regsvr32.exe
//vb写法
shell "regsvr32.exe 控件.ocx /s "
//vc写法
::ShellExecute(NULL,NULL,"regsvr32.exe","/s D:\\新建文件夹\\TEST\\TEST\\Release\\TEST.reg ",NULL,NULL);
//添加REG文件进入注册衿/P&gt;
::ShellExecute(NULL,NULL,"regedit.exe","/s D:\\新建文件夹\\TEST\\TEST\\Release\\TEST.reg ",NULL,NULL);
注释＿s标题不弹出消息框〿/P&gt;

小小经验＿/STRONG&gt;
1、有时候在程序中使用ocx控件时失效，检查一下调用之间是否执行了afxoleinit()。如果使用了容器，还需要保证执行了 afxEnableControlContainer()
2、使用Activex Control Test Container 可以很方便地测试制作出来的ocx控件（从开始菜单－》程序－》Microsoft Visual Studio 6.0 -&gt; Microsoft Visual Studio 6.0 Tools 可以看到该工具）
3、有时候控件制作的没有问题，注册方式也对，但是注册的时候确失败了，可能时dll的版本不寿使用Dependencies查看ocx控件依赖dll是否跟现在使用的dll版本一致〿/P&gt;
regsvr32.exe 命令说明和参敿/STRONG&gt;
“regsvr32 [/s] [/n] [/i(:cmdline)] dllname”。其中dllname为activex控件文件名，建议在安装前拷贝到system文件夹下〿/P&gt;
参数有如下意义：
/u——反注册控件
/s——不管注册成功与否，均不显示提示桿/P&gt;
/c——控制台输出
/i——跳过控件的选项进行安装(与注册不吿
/n——不注册控件，此选项必须丿i选项一起使甿/P&gt;
执行该命令的方法＿/P&gt;
1、可以在“开始‿-“运行”，调出运行的对话框，也可以使用Win+R热键，然后直接在输入栏输入即叿/P&gt;
2、在开姿-运行 输入cmd，调出‘命令提示符’窗口，然后再执行regsvr32命令〿/P&gt;

方法三示例：
注册控件
BOOL CYourClass::RegistOcx()
{
    HINSTANCE hLib = LoadLibrary("NTGraph.ocx");      //指定要注册的ocx文件的路径及文件名〿BR&gt; 
    if (hLib == NULL)
    {
         MessageBox("不能载入OCX文件!");
         return;
    }
    //获取注册函数DllRegisterServer地址
    FARPROC lpDllEntryPoint;
    lpDllEntryPoint = GetProcAddress(hLib,"DllRegisterServer");
    //调用注册函数DllRegisterServer
    if(lpDllEntryPoint!=NULL)
    {
        if(FAILED((*lpDllEntryPoint)()))
        {
            //MessageBox(Handle,"调用DllRegisterServer失败!","失败ing..",MB_OK);
            MessageBox("OCX注册失败!");
            FreeLibrary(hLib);
            return;
        };
        //MessageBox(Handle,"注册成功!","Reg",MB_OK);
        MessageBox("OCX注册成功!");
    }
    else
        MessageBox("OCX注册失败!");
        //MessageBox(Handle,"调用DllRegisterServer失败!","失败ing..",MB_OK);
}
卸载控件
BOOL CYourClass::UnRegistOcx()
{
    HINSTANCE hLib = LoadLibrary("NTGraph.ocx");          //指定要卸载的ocx文件的路径及文件名〿BR&gt;    if (hLib==NULL)
    {
        //MessageBox(Handle,"不能载入Dll文件!","失败ing..",MB_OK);
        MessageBox("不能载入OCX文件!");
        return;
    }
    //获取注册函数DllRegisterServer地址
    FARPROC lpDllEntryPoint;
    lpDllEntryPoint = GetProcAddress(hLib,"DllUnregisterServer");//注意这里是DllUnregisterServer〿/P&gt;
    //调用注册函数DllRegisterServer
    if(lpDllEntryPoint!=NULL)
    {
        if(((*lpDllEntryPoint)()))
        {
            //MessageBox(Handle,"调用DllUnRegisterServer失败＿,"失败ing..",MB_OK);
            MessageBox("调用DllUnRegisterServer失败!!!");
            FreeLibrary(hLib);
            return;
        };
        //MessageBox(Handle,"注销成功＿,"Unreg",MB_OK);
        MessageBox("OCX注销成功＿);
    }
    else
    //MessageBox(Handle,"调用DllUnRegisterServer失败!!!","结果",MB_OK);
        MessageBox("OCX调用DllUnRegisterServer失败!!!");
}
判断是否注册  
BOOL CYourClass::IsRegistOcx()
{
    HKEY hKey;     
    BOOL bPresent;     
    TCHAR szPath[_MAX_PATH];     
    DWORD dwRegType;     
    DWORD cbData   =   sizeof   szPath   *   sizeof   TCHAR;    
   if(RegOpenKeyEx(HKEY_CLASSES_ROOT,"ActiveX.ActiveXControl\\Clsid",0,KEY_READ,&amp;hKey)!=ERROR_SUCCESS)
        return false;
    else
        return true;
  //ActiveX.ActiveXControl为控件的名称和内部名称   如"NTGRAPH.NTGraphCtrl.1\\CLSID"
}</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=574</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VC开发OCX</title>
		<link>https://www.softwareace.cn/?p=572</link>
		<comments>https://www.softwareace.cn/?p=572#comments</comments>
		<pubDate>Tue, 17 Sep 2013 06:12:57 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[activex]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=572</guid>
		<description><![CDATA[开篇语：最近在弄ocx控件发布到asp.net网站上使用，就是用户在使用过程中，自动下载安装ocx控件。（此文 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>开篇语：最近在弄ocx控件发布到asp.net网站上使用，就是用户在使用过程中，自动下载安装ocx控件。（此文章也是总结了网上好多人写的文章，我只是汇总一下，加上部分自己的东西，在这里感谢所有在网上发表相关内容的朋友们。）</p>
<p><a href="http://en.wikipedia.org/wiki/ActiveX">ActiveX</a>控 件用于Web的过程是将控件嵌入主页中，用户通过浏览器访问该主页时，将主页中的控件下载，并在用户机器上注册，以后就可在用户的浏览器上运行。控件下载 一次后就驻留在用户本地机器上，下次再访问相同的主页时，可不再下载该控件，而是直接运行用户本地的控件。这里控件容器就是浏览器，用户不需要通过浏览器 调用控件的属性或方法。因此，开发面向Web的ActiveX控件比开发桌面的控件还要简单些，所复杂的是如何将该控件很好地嵌入主页，使用户能正常浏览。下面介绍这个问题。</p>
<p><strong>一．        </strong><strong>创建</strong><strong>MFC ActiveX</strong><strong>项目</strong></p>
<p>1.       打开VS2005新建MFC项目。这里我们取名为“ActiveXDemo”。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image001.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image001.jpg" width="593" height="394" /></a></p>
<p>&nbsp;</p>
<p>2.       输入项目名称为“ActiveXDemo”和项目位置。点击“确定”按钮，打开向导对话框。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image002.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image002.jpg" width="553" height="405" /></a></p>
<p>WoSign 免费提供的时间戳服务URL： <strong>http://timestamp.wosign.com/timestamp</strong></p>
<p>时间戳服务非常重要，添加时间戳后，即使您的代码签名证书已经过期，但由于您的代码是在证书有效期内签名的，则时间戳服务保证了此代码仍然可信，最终用户仍然可以放心下载，使得即使代码签名证书已经过期，您也无需重签和重新发布已经签名的代码。</p>
<p>&nbsp;</p>
<p>3.       选择“控件设置”选项卡，具体设置可参考上图。其它选项卡为默认设置。最后点击“完成”按钮保存设置。</p>
<p>&nbsp;</p>
<p><strong>二．        </strong><strong>添加控件方法</strong></p>
<p>VC2005会为我们自动创建好MFC <a href="http://en.wikipedia.org/wiki/ActiveX">ActiveX</a>程序框架，我们只要给该ActiveX控件添加方法即可。现在我们给控件添加一个“AddFun”方法，这个方法是将两个数相加并返回结果。</p>
<p>1.       点击“视图”，打开“类视图”窗口。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image003.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image003.jpg" width="355" height="330" /></a></p>
<p>2.       展开“ActiveXDemoLib”项，选中“_DActiveXDemo”项。点击鼠标右键，选择“添加”下的“添加方法”。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image004.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image004.jpg" width="313" height="321" /></a></p>
<p>&nbsp;</p>
<p>3.       打开添加方法向导窗口。因为我们是添加一个加法方法，所以我们设置的返回类型为LONG型，方法名设为AddFun，添加两个LONG类型参数Add1，Add2。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image005.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image005.jpg" width="553" height="405" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>4.       其它为默认设置，点击“完成”按钮完成添加方法。接下来我们打开“解决方案资源管理器”打开“ActiveXDemoCtrl.cpp”文件。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image006.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image006.jpg" width="357" height="380" /></a></p>
<p>5.       打开代码视图，我们会发现VC2005已经为我们添加了一个“AddFun”方法，我们在方法内添加“return Add1 + Add2;”语句。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/image007.jpg" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/image007.jpg" width="554" height="364" /></a></p>
<p><strong> </strong></p>
<p><strong> 三、MFC Activex 安全问题：</strong></p>
<p>1、在默认环境下，编译的MFC Activex控件，只能在本地代码中运行，即在http://localhost/xxx/xxx.htm中执行，而在http://127.0.0.1/xxx/xxx.htm中提示无相关属性,需要设置其初始化和脚本运行的安全性</p>
<p>ActiveX在远程IE页面上执行，需要实现安全接口。</p>
<p>在ATL写的ActiveX中，用IObjectSafety。</p>
<p><a href="http://support.microsoft.com/kb/168371/en-us">http://support.microsoft.com/kb/168371/en-us</a></p>
<p>在MFC写的ActiveX中，直接修改注册表。</p>
<p><a href="http://support.microsoft.com/kb/161873/en-us">http://support.microsoft.com/kb/161873/en-us</a></p>
<p>mfc实现的ocx，要在app实现文件中包括两个文件：</p>
<p>在ActivexDemo.cpp 文件中实现以下方法</p>
<p>&nbsp;</p>
<div><a href="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" /></a> 代码</p>
<div id="cnblogs_code_open_42cd5e63-f487-4776-a05a-e42887b6609a">
<div>#include  &#8221; stdafx.h &#8221;<br />
#include  &#8221; ActivexDemo.h &#8221;<br />
#include  &lt; comcat.h &gt;<br />
#include  &lt; objsafe.h &gt;<br />
#ifdef _DEBUG<br />
#define  new DEBUG_NEW<br />
#endif</p>
<p>CActivexDemoApp theApp;</p>
<p>const  GUID CDECL BASED_CODE _tlid  =<br />
{  0x344B8576 ,  0xAB2C ,  0x4D38 , {  0xAE ,  0&#215;7 ,  0&#215;73 ,  0&#215;74 ,  0&#215;22 ,  0&#215;89 ,  0&#215;72 ,  0xEA  } };<br />
const  WORD _wVerMajor  =   1 ;<br />
const  WORD _wVerMinor  =   0 ;</p>
<p>//  CActivexDemoApp::InitInstance - DLL 初始化</p>
<p>BOOL CActivexDemoApp::InitInstance()<br />
{<br />
BOOL bInit  =  COleControlModule::InitInstance();</p>
<p>if  (bInit)<br />
{<br />
//  TODO: 在此添加您自己的模块初始化代码。<br />
}</p>
<p>return  bInit;<br />
}</p>
<p>//  CActivexDemoApp::ExitInstance - DLL 终止</p>
<p>int  CActivexDemoApp::ExitInstance()<br />
{<br />
//  TODO: 在此添加您自己的模块终止代码。</p>
<p>return  COleControlModule::ExitInstance();<br />
}</p>
<p>//  创建组件种类<br />
HRESULT CreateComponentCategory(CATID catid, WCHAR *  catDescription)<br />
{<br />
ICatRegister *  pcr  =  NULL ;<br />
HRESULT hr  =  S_OK ;<br />
hr  = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void ** ) &amp; pcr);<br />
if  (FAILED(hr))  return  hr;<br />
//  Make sure the HKCR\Component Categories\{..catid&#8230;}<br />
//  key is registered.<br />
CATEGORYINFO catinfo;<br />
catinfo.catid  =  catid;<br />
catinfo.lcid  =   0&#215;0409  ;  //  english<br />
//  Make sure the provided description is not too long.<br />
//  Only copy the first 127 characters if it is.<br />
int  len  =  wcslen(catDescription);<br />
if  (len &gt; 127 ) len  =   127 ;<br />
wcsncpy(catinfo.szDescription, catDescription, len);<br />
//  Make sure the description is null terminated.<br />
catinfo.szDescription[len]  =   &#8216; \0 &#8216; ;<br />
hr  =  pcr -&gt; RegisterCategories( 1 ,  &amp; catinfo);<br />
pcr -&gt; Release();<br />
return  hr;<br />
}</p>
<p>//  注册组件种类<br />
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)<br />
{<br />
//  Register your component categories information.<br />
ICatRegister *  pcr  =  NULL ;<br />
HRESULT hr  =  S_OK ;<br />
hr  = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void ** ) &amp; pcr);<br />
if  (SUCCEEDED(hr)) {<br />
//  Register this category as being &#8220;implemented&#8221; by the class.<br />
CATID rgcatid[ 1 ];<br />
rgcatid[ 0 ]  =  catid;<br />
hr  =  pcr -&gt; RegisterClassImplCategories(clsid,  1 , rgcatid);<br />
}<br />
if  (pcr  !=  NULL) pcr -&gt; Release();<br />
return  hr;<br />
}<br />
//  卸载组件种类<br />
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)<br />
{<br />
ICatRegister *  pcr  =  NULL ;<br />
HRESULT hr  =  S_OK ;<br />
hr  =  CoCreateInstance(CLSID_StdComponentCategoriesMgr,<br />
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, ( void ** ) &amp; pcr);<br />
if  (SUCCEEDED(hr)) {<br />
//  Unregister this category as being &#8220;implemented&#8221; by the class.<br />
CATID rgcatid[ 1 ] ;<br />
rgcatid[ 0 ]  =  catid;<br />
hr  =  pcr -&gt; UnRegisterClassImplCategories(clsid,  1 , rgcatid);<br />
}<br />
if  (pcr  !=  NULL) pcr -&gt; Release();<br />
return  hr;<br />
}<br />
STDAPI DllRegisterServer( void )<br />
{<br />
HRESULT hr;<br />
AFX_MANAGE_STATE(_afxModuleAddrThis);<br />
if  ( ! AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))<br />
return  ResultFromScode(SELFREG_E_TYPELIB);<br />
if  ( ! COleObjectFactoryEx::UpdateRegistryAll(TRUE))<br />
return  ResultFromScode(SELFREG_E_CLASS);<br />
//  标记控件初始化安全.<br />
//  创建初始化安全组件种类<br />
hr  =  CreateComponentCategory(CATID_SafeForInitializing, L &#8220;Controls safely initializable from persistent data! &#8221; );<br />
if  (FAILED(hr))  return  hr;<br />
//  注册初始化安全<br />
hr  =  RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForInitializing);<br />
if  (FAILED(hr))  return  hr;<br />
//  标记控件脚本安全<br />
//  创建脚本安全组件种类<br />
hr  =  CreateComponentCategory(CATID_SafeForScripting, L &#8221; Controls safely scriptable! &#8221; );<br />
if  (FAILED(hr))  return  hr;<br />
//  注册脚本安全组件种类<br />
hr  =  RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);<br />
if  (FAILED(hr))  return  hr;<br />
return  NOERROR;<br />
}<br />
//  DllUnregisterServer - Removes entries from the system registry<br />
STDAPI DllUnregisterServer( void )<br />
{<br />
HRESULT hr;<br />
AFX_MANAGE_STATE(_afxModuleAddrThis);<br />
if  ( ! AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))<br />
return  ResultFromScode(SELFREG_E_TYPELIB);<br />
if  ( ! COleObjectFactoryEx::UpdateRegistryAll(FALSE))<br />
return  ResultFromScode(SELFREG_E_CLASS);<br />
//  删除控件初始化安全入口.<br />
hr = UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForInitializing);<br />
if  (FAILED(hr))  return  hr;<br />
//  删除控件脚本安全入口<br />
hr = UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);<br />
if  (FAILED(hr))  return  hr;<br />
return  NOERROR;<br />
}</p></div>
</div>
</div>
<p>&nbsp;</p>
<p>现在控件就可以在自注册时就注册为安全控件了。</p>
<p>2、设置项目属性 将配置类型设置成静态库(.lib)</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/shuxing.JPG" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/shuxing.JPG" width="683" height="448" /></a></p>
<p>&nbsp;</p>
<p>3、       最后生成项目，ocx控件就产生了。</p>
<p>&nbsp;</p>
<p><strong> ActiveX打包与发布</strong></p>
<p>在VS2005或VS2008安装后发现路径**VC7\Common7\Tools\Bin\下有许多小工具，我对带有Cert的文件比较感兴趣。经过研究，发现是有关证书和签名的，当然，该证书未被证书认证机构认可。下面列出这些工具和我的使用心得。<br />
1。Makecert.exe &#8212;证书创建工具<br />
2。Cert2Spc.exe &#8212;发行者证书测试工具<br />
3。Signcode.exe &#8212;文件签名工具（VS2008带的是signtool）<br />
一、ActiveX发布步骤</p>
<p>在这里简单说明下，打包activeX需要制作证书，具体用到makecert 、cert2spc 、signtool 这三个VS提供的工具，工具在VS文件夹里面，以下制作过程需要在工具所在的文件夹下完成！<br />
1、单击&#8221;开始&#8221;&#8211;&gt;&#8221;运行（R）&#8221;&#8211;&gt;输入&#8221;cmd&#8221;&#8211;&gt;回车&#8211;&gt;进入到操作的控件所在的目录（需要将上面所说的工具，和ocx控件放到一个文件夹下）；<br />
2、创建PVK文件(私人密匙文件)，在命令行中输入&#8221;makecert -sk demo demo.pvk -n CN=XXXXXXX公司&#8221;，然后回车；</p>
<p>sk-表示主题的密钥容器位置，ss-主题的证书存储名称， n-证书颁发对象，r-证书存储位置；</p>
<p>3、创建CER文件(公司证书)，在命令行中输入&#8221;makecert -sk demo.pvk demo.cer&#8221;，然后回车，如图8所示，若出现&#8221;Successed&#8221;提示，则会在E:\ demo目录下生成demo.cer文件；</p>
<p>sk-表示主题的密钥容器位置，is-颁发者的证书存储名称， n-证书颁发对象，ic-颁发者的证书存储位置，-$-授权范围（用于代码签名）；</p>
<p>4、创建SPC测试软件出版商证明书，在命令行中输入&#8221;cert2spc demo.cer demo.spc&#8221;，然后回车；</p>
<p>5、创建INF文件，用记录本编辑以下信息：</p>
<p>&nbsp;</p>
<div><a href="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" /></a> 代码</p>
<div id="cnblogs_code_open_9b4a02c3-f4a5-4a69-a8ad-903a524f421d">
<div>[ version ]</p>
<p>signature = &#8221; $CHICAGO$ &#8221;</p>
<p>AdvancedINF = 2.0</p>
<p>[ Add.Code ]</p>
<p>ActivexDemo.ocx = ActivexDemo.ocx</p>
<p>[ ActivexDemo.ocx ]</p>
<p>file-win32-x86 = thiscab<br />
// 告诉ie到哪里去得到这个dll，file一共包括三个部分，第一部分是file，这个永远都是这样的（至少目前来说）；第二部分告诉声明支持的 OS，win32表示windows，mac就是苹果MAC  OX了；第三部分是CPU类型，比如说 x86、  ppc  (Power  PC)、  mips或者alpha了<br />
//其中“thiscab”是一个关键字，表示 CAB 包含此 DLL，也可通过指定一条绝对或相对路径，从一个 HTTP 位置下载所需的 DLL，<br />
例如:  file-win32-x86 = http://www.mysite.com/mydir/NEEDED.DLL<br />
RegisterServer = yes</p>
<p>clsid = { 468E4531 -F890-47EC- 8368 -3BDA4448FF08}<br />
//“clsid”是将要安装的控件的 CLSID<br />
DestDir = 11<br />
// 它的值是dll将要存到本地硬盘的位置，如果它的值是10，则将dll放到\Windows或者\WinNT下；如果是11，则放到\Windows \System或者\WinNT\System32下；如果未指定任何 DestDir（典型情况），则代码安装在固定的 OCCACHE 目录中。<br />
FileVersion = 1 , 0 , 0 , 1<br />
//说明了atl90.dll的版本号</p></div>
</div>
</div>
<p>6、创建CAB文件，在命令行中输入&#8221;cabarc -s 6144 n demo.cab atl90.dll Polygon.dll demo.inf&#8221;，-s 选项表示在压缩文件中保留用于代码签名的空间，n命令指定希望创建 CAB 文件，然后回车；</p>
<p>7、使用<a href="http://en.wikipedia.org/wiki/Code_signing">Code Signing</a> Wizard签署一个CAB文件，在控制台输入signtool signwizard 进入到signtool窗体中;</p>
<p>8、单击&#8221;下一步（N）&#8221;按钮，选择要进行数字签名的且已做成CAB包的文件demo.cab文件；</p>
<p>9、选择好CAB包后单击&#8221;下一步（N）&#8221;按钮，在选择想要的签名类型里选择&#8221;自定议（C）&#8221;并单击&#8221;下一步（N）&#8221;按钮；</p>
<p>10、接下来单击&#8221;从文件选择（F）&#8221;按钮，选择刚刚制作的demo.cer；</p>
<p>11、在单击&#8221;下一步（N）&#8221;，然后选择&#8221;CSP中的私钥（K）&#8221;；</p>
<p>13、在&#8221;证书路径中的证书&#8221;中选择&#8221;证书路径中的所有证书，包括根证书（C）&#8221;，在&#8221;其它证书（可选）&#8221;中选择&#8221;包括在以下PKCS #7 证书（.p7b）文件中的证书（P）：&#8221;，并单击&#8221;浏览（R）&#8230;&#8221;按钮选择demo.spc文件，选择完后单击&#8221;下一步（N）&#8221;按钮；</p>
<p>14、接下来在弹出的&#8221;数据描述&#8221;窗口中输入公司的名称和网址并单击&#8221;下一步（N）&#8221;按钮；</p>
<p>15、现大部份工作都已完成，在接下来的一步当中是可选的操作，其作用只是为CAB加入时间戳，此步骤完全可以不做，VeriSign:  <a href="http://timestamp.verisign.com/scripts/timstamp.dll">http://timestamp.verisign.com/scripts/timstamp.dll</a>；</p>
<p>16、完成，单击&#8221;下一步（N）&#8221;按钮便可来到数字签名向导的最后一步，即操作总览，如图26所示，单击&#8221;完成&#8221;按钮便可大功告成；</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>下面是微软代码签名证书(.pvk/.spc)签名指南的演示</strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>本使用指南演示如何使用WoSign代码签名证书来给微软代码签名,Thawte和VeriSign代码签名证书也是使用同样方法,只是使用不同的时间戳URL。</p>
<p>用户在在线申请代码签名证书时会生成证书私钥文件，如：myCert.pvk，而代码签名证书成功颁发后的证书文件为公钥文件， 如：myCert.spc，又称：软件发行证书(Software Publishing Certificate) 。 代码签名证书一般都是采用公钥和私钥分离的两个文件方式，适合于 DOS 命令行方式的代码签名。如果您您希望把代码签名证书导入到Windows证书存储区中，从而简化签名操作，请参考：<a href="http://www.wosign.com/support/PVK_SPC2PFX.htm">不同证书格式转换指南</a>。</p>
<p>WoSign代码签名证书的根证书链为： <a href="http://www.wosign.com/Root/UTN_Object.cer">UTN-USERFirst-Object </a>- <a href="http://www.wosign.com/Root/WoSign_CodeSigning.crt">WoSign Code Signing Authority</a></p>
<p>使用微软的 <strong>SignCode.exe</strong> 就可以对微软的代码进行签名，如果您没有此文件，点击 <a href="http://www.wosign.com/download/signtool.rar">这里 </a>下载。 Signcode.exe 可以使用 DOS 命令行方式实现签名，我们推荐用户使用数字签名向导方式，简单方便。请注意：如果您开发的ActiveX为IE加载项，请先数字签名每个CAB文件中的.dll和.ocx等文件，再把这些文件打包成.cab文件后再数字签名.cab文件，以确保所有IE加载项都被IE验证和信任，否则会显示“未验证”而可能影响正常运行。</p>
<p>具体签名向导过程如下：</p>
<p>(1) 运行 Signcode.exe ， 要求您选择需要签名的文件，支持：可执行文件 (*.exe; *.dll; *.ocx) ； Cabinet 打包文件 (*.cab) 和目录文件 (*.cat) ，如下图 1 所示 ( 如： TestSign.cab) ，请注意：如果签名的文件已经有数字签名，则会被新的签名覆盖：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/1.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/1.gif" /></a></p>
<p>(2) 点击“下一步”后，如下图 2 所示，会要求您选择“签名类型”，缺省的“典型”签名类型；请选择“自定义” 签名类型：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/2.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/2.gif" width="503" height="358" /></a></p>
<p>(3) 如下图 3 所示，点击“从文件选择”签名证书 ( 公钥文件 )，如： WotoneCS.spc ：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/3.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/3.gif" width="503" height="358" /></a></p>
<p>(4) 点击“下一步”后，如下图 4 所示，会要求您选择私钥文件，如： WotoneCS.pvk ，其他参数不用动：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/4.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/4.gif" width="503" height="358" /></a></p>
<p>(5) 点击“下一步”后，如下图 5 所示，会提示要求输入私钥密码：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/5.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/5.gif" width="503" height="358" /></a></p>
<p>(6) 点击“下一步”后，如下图 6 所示，会提示要求选择散列算法 ( 摘要算法、缩微图算法 ) ，缺省为 sha1 ，也可以选 md5 ：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/6.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/6.gif" width="503" height="358" /></a></p>
<p>(7) 点击“下一步”后，如下图 7 所示，选择哪些证书包括到数字签名中，直接点击“下一步”即可，即选择缺省的包括根证书：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/7.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/7.gif" width="503" height="358" /></a></p>
<p>(8) 如下图 8 所示，要求填写该签名代码的功能描述，推荐一定要认真填写，因为此信息将会在最终用户下载此代码时显示，有助于最终用户了解此代码的功能以确定是否下载安 装。第一行“描述”是指此代码的功能文字描述，第二行“ Web 位置”则让最终用户点击文字描述来详细了解此代码的功能和使用方法等，本演示中的“ Web 位置”为WoTrust代码签名证书简介页面：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/8.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/8.gif" width="503" height="380" /></a></p>
<p>(9) 点击“下一步”后，如下图 9 所示，选中“将时间戳添加到数据中”，请使用:</p>
<p>&nbsp;</p>
<p>WoSign 免费提供的时间戳服务URL： <strong>http://timestamp.wosign.com/timestamp</strong></p>
<p>时间戳服务非常重要，添加时间戳后，即使您的代码签名证书已经过期，但由于您的代码是在证书有效期内签名的，则时间戳服务保证了此代码仍然可信，最终用户仍然可以放心下载，使得即使代码签名证书已经过期，您也无需重签和重新发布已经签名的代码。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/9.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/9.gif" width="502" height="380" /></a></p>
<p>(10) 点击“下一步”后，如下图 10 所示，会提示已经完成数字签名向导，点击“完成”后还会提示您输入私钥密码，就完成代码签名证书的代码签名。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/10.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/10.gif" width="503" height="358" /></a></p>
<p>(11) 现在，需要使用 chktrust.exe 来查验已经签名的代码， chktrust.exe 文件已经打包在 <a href="http://www.wosign.com/download/signtool.rar">signtool.rar</a>中。 进入 DOS 命令提示符，并进入已经签名的文件所在目录 ( 如： d:\sign\TestCA.cab) ，键入命令： chktrust testcs.cab ，则会显示实际应用时在 IE 浏览器下载页面的情况，如下图 11 所示，对于Win XP操作系统，会显示软件名称和发行者名称，其中软件名称就是您在第(8)步输入的描述，点击此名称就链接到您在第(8)步填写的网址，而点击发行者名 称，则会显示您的签名信息和时间戳信息。对于Win2000操作系统，则稍有不同，第 1 行的红线部分就是时间戳记录的签名时的本地时间，请注意：此时间不是取签名电脑的时间，而是提供时间戳服务的服务器计算出来的签名电脑设置的所在时区的本 地时间。第 1 行蓝色文字就是在第 8 步中输入的描述文字，点击此蓝色文字就可以访问在第 8 步中输入的 Web 描述页面。第 2 行蓝色文字则为该代码的发行者，也就是代码签名证书的申请者(拥有者)( 如：深圳市沃通电子商务服务有限公司) ，点击可以查看证书的详细信息；第 2 行有红色下划线部分显示“发行商可靠性由 WoSign <a href="http://en.wikipedia.org/wiki/Code_signing">Code Signing</a>Authority 验证 ”就是此代码签名证书的证书颁发者。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/11.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/11.gif" width="464" height="513" /></a></p>
<p>12) 点击“是”或“运行”，则会提示“ TestSign.cab: Succeeded ”表示代码 TestSign.cab 签名验证有效，可以放到网站上了。请注意：签名后的CAB文件放到网站上需要使用 object 方式。</p>
<p><strong>请注意</strong>：不能仅签名CAB文件，CAB包中所有DLL文件都要先签名后再打包，再签名CAB文件，否则IE浏览器会显示为“未验证的发行者”而影响正常使用，甚至杀毒软件会认为是毒而被删除！如下图所示的实际案例：</p>
<p>&nbsp;</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/gengaixue/12.gif" target="_blank"><img alt="" src="http://images.cnblogs.com/cnblogs_com/gengaixue/12.gif" /></a></p>
<p>&nbsp;</p>
<h4>在Web页中加入ActiveX 控件</h4>
<p>在修改了IE的安全设置后，依然不能调用控件的方法，需要将访问的站点设置为“受信站点”，则方能正常使用控件<br />
在&lt;html&gt; 和&lt;head&gt;之间插入<br />
&lt;!&#8211; saved from url=(0017)http://localhost/ &#8211;&gt;<br />
则在IE窗口上方不会弹出黄色提示条 。</p>
<p>在HTML页面中使用ActiveX控件包含三个基本操作：将控件放入HTML中；将该控件下载给用户；在用户机器上安装该控件。如果只是针对IE用户，在HTML中插入ActiveX控件就比较简单；如果同时兼顾IE和Netscape用户，则要做更多工作。大家知道，HTML文件由文本和各种标志(tags)组成，ActiveX 控件对于IE在HTML中的标志是＜OBJECT＞，该标记有几个重要的参数特性，它们是：</p>
<p>1.ID：为控件提供一个标识名称，为HTML代码提供一种访问该控件的方式。</p>
<p>2.CLASSID：是该控件唯一的UUID，告诉IE装入哪个对象。如果使用已经开发好的控件，它的CLASSID可以通过调用Win95或NT下的应 用Regedit来查找。从开始菜单中运行该程序，展开HKEY_CLASSES_ROOT项，可以看到按字母顺序排列的注册表，找到需要使用的控件名， 例如WClnt，展开时可看到一个<a href="http://en.wikipedia.org/wiki/Globally_unique_identifier">CLSID</a>文件夹，里面就是该控件的CLASSID。</p>
<p>如果是自己用VC开发控件，该UUID可以在ActiveX控件项目中的ODL（对象描述库）文件中找到；通过查看控件的类信息注释来定位特定控件的UUID，例如，要找到CMyControl控件的UUID，则需要找到以下代码：</p>
<p>// Class information for CMyControl</p>
<p>[uuid (051C4748－1262－11D2－87C1－00A024D948FB),</p>
<p>licensed,</p>
<p>helpstring(“CmyControl Control”), control ]</p>
<p>uuid后面括号中的内容就是该控件的UUID。</p>
<p>3.CODEBASE：如果在用户机器上没有控件的当前版本，该参数告诉用户浏览器在哪里可找到要下载的控件和最新版本号.当控件作了修改后，可以更改版本号强制用户重新下载。</p>
<p>4.PARAM：该标记用于设置控件的初始属性值，它有两个特性：Name和Value，即属性名称和属性值。</p>
<p>此外还有一些标记，如：Width表示该控件所占的宽度，Height表示高度等，总体来说，这样一个插入控件的HTML代码和插入Java Applet的HTML代码非常相似。</p>
<p>下面是一个嵌有ActiveX控件的HTML代码示例：</p>
<p>&nbsp;</p>
<p>ID=“CMyControl”</p>
<p>CLASSID=“<a href="http://en.wikipedia.org/wiki/Globally_unique_identifier">clsid</a>:051C4748－1262－11D2－87C1－00A024D948FB ”</p>
<p>CODEBASE=“http://www.mysite.com.cn/ocxdir/mycontrol.ocx＃version=1,0,0,1”</p>
<p>WIDTH=400</p>
<p>HEIGHT=200</p>
<p>ALIGN=center</p>
<p>HSPACE=0</p>
<p>VSPACE=0</p>
<p>＞</p>
<p>如果希望控件还 能在Netscape中运行，除了Netscape需加装插件外，HTML也要加一些附加标记，下面的例子中EMBED段就是为Netscape加上的。 如果使用MFC开发OCX控件，则少数用户第一次访问时除了下载OCX文件外，还要下载相应的MFC DLL，下载量变大，这时可将相关文件在服务器端打包成可以在客户端自解压安装的CAB文件。经过修改后的HTML代码段如下：</p>
<p>＜ALIGN=“CENTER” CLASSID=“clsid:</p>
<p>7BCA18C6－2178－11D2－87C1－00A024D948FB”</p>
<p>WIDTH=“1200” HEIGHT=“900” ID=“marquee”</p>
<p>CODEBASE=“http://218.168.188.188/scadaweb/</p>
<p>WClnt.cab＃version=1,0,0,1”＞</p>
<p>＜EMBED ALIGN=“CENTER”CLASSID=“clsid:7BCA18C6－ 2178－11D2－87C1－00A024D948FB”</p>
<p>WIDTH=“1200” HEIGHT=“900” ID=“marqueequot;”</p>
<p>CODEBASE=“http://218.168.188.188/scadaweb/</p>
<p>WClnt.OCX＃version=1,0,0,1”</p>
<p>TYPE=“application/oleobject” ＞</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>实时动态页面的实现方案</h4>
<p>对实时动态页面的要求多产生于一些要求自动更新实时数据的应用中，如电网监控、股市监测等。具体要求是：用户只需选取希望浏览的图表，但无需介入操作，该图表就能根据实时数据不断更新，用户总能观察到最新情况。</p>
<p>要实现上述功 能，结构上有两种方案：一种是设置一个中介服务器，该服务器作为控件和后台系统信息交流的中介；另一种是不设中介服务器，但在提供实时数据的后台服务器上 留出供控件通信用的数据接口，控件可以直接从后台服务器上定时获得当前实时数据。按数据提供方式分也有两种：一种是由客户端定时向服务器发出请求，指明需 要的实时数据，服务器收到请求后将满足请求的动态数据发送至相应客户；另一种是客户端只请求一次，服务器端便定时将满足请求的实时数据传到客户端，直到客 户更换要显示的图表或停止刷新。上述各方案都有其优点和局限，在应用中可考虑实际情况采用相应方案。</p>
<p>工作流程为：用户先从Web服务器上下载包含ActiveX 控件的网页，控件随即在客户机上注册运行，并通过Winsock同中介服务器或直接同提供实时信息的网，如股票信息网相连接，定时取得动态实时数据，并刷 新显示。在这个体系中，客户有两条线路获得信息，一条是和Web Server的连接，从这条线上用户访问主页；另一条就是控件和后台信息网的连接，从这条线路上用户可以访问实时数据。后一条线路用Winsock建立， 传输速度远大于前一条线路，且控制灵活、效率高，不和主页下载争资源。通过这条线路，用户甚至可以传送远程控制信息实现遥控操作。</p>
<h4>利用MFC开发ActiveX控件</h4>
<p>利用VC5.0 开发的这种控件，功能可扩展性强，理论上独立的VC5.0程序具有的功能，该控件都能实现，例如控件直接绘制浏览器，可以使用OpenGL等图库，图形图 像功能强大。实时数据刷新频率理论上可达毫秒级，用户通过鼠标可以实现各类交互操作，如旋转、缩放，图2就是一幅GL图形，并有一个缩放工具条进行缩放操 作。如果是在计算机上观看，可以看到这几个三维图在不断旋转。</p>
<p>应该说，较好的开发工具可直接用API编程或使用ATL模板库，利用MFC开发ActiveX控件不是一个好的选择，因为控件运行需要MFC DLL的支持。假如客户机器上没有这些类库（这种情况很少，但确实存在），第一次下载就要花费些工夫。不过对于熟悉MFC的开发员来说，这些问题相对MFC提供的便利来说都是可以忽略的。</p>
<p>由于VC5.0对ActiveX控件的开发提供了许多便利，所以开发一个ActiveX控 件并不像许多人想象中的那么困难复杂，通过VC 5.0的AppWizard，实现控件的主类从ColeControl类派生出来，该类则是CWnd的一个子类，所以你可以像对窗口类编程一样对这个主类 编程。为了实现上面提及的功能，首先必要重载它的OnDraw函数加入需要绘制的对象，加入Winsock类（CSocket或 CAsyncSocket），以实现与后端数据服务器的通信。如果需要用OpenGL绘制丰富多彩的立体图，则要初始化GL环境。其他的工作就在于用户如 何控制程序的调度，使得各功能都能正常工作且与其他部分正常通信。此外，后端服务器程序也要增加对应于该控件的接口。</p>
<p>这样的一个程序编译通过后，就成为一个可用于Web的控件，后缀名是OCX。按照前面叙述的方法将该OCX置入主页，基本的工作就算完成。</p>
<p>综上所述，利用VC5.0开发ActiveX控件用于Web浏览，主要有以下几个特点：</p>
<p>1．采用Winsock的通信机制，速度快、控制灵活、效率高；</p>
<p>2．控件采用VC5.0编制，功能可扩展性很强；</p>
<p>4．控件第一次下载虽然稍费时间，但下载后即在用户机上注册，以后可直接调用，速度效率均好；</p>
<p>5．ActiveX技术是微软发展的重中之重，且已成为当前软件发展的潮流所向，发展空间广阔；</p>
<p>6．系统采用VC开发，可以利用已有的采用C语言编制的系统，开发工作量大大减少。</p>
<p>Web页面的开发主要分为三类：静态Web页面、半动态Web页面以及Client端动态页面。本文重点论述基于ActiveX Control(控件)动态实时页面的开发。</p>
<p><a href="http://en.wikipedia.org/wiki/Regsvr32">regsvr32</a> netshare.ocx        注册netshare.ocx控件</p>
<p>regsvr32 /u netshare.ocx    解除netshare.ocx控件的注册</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=572</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
