近期在做一个 WEB 项目。须要调用 OCX 进行连接读卡器读卡。本来并不想用 OCX 技术。由于 ActiveX 技术是微软出品。这样就导致整个系统仅仅能使用 IE 浏览器(其它浏览器能够通过插件的形式支持 OCX 的调用)。但尝试了非常多方法调用client DLL 发现都走不通。最后无奈之下,才打算研究 OCX 技术。
    网上都说 ActiveX 技术非常麻烦,会出现各种错误。不做的时候不知道,真正须要研究时候,才发现确实如此。

主要问题是,报错和问题的真正原因没有关系或者说关系不大。甚至非常多时候没有报错。仅仅有不断尝试。

    言归正传,以下来讲一下怎样搞定 OCX。

    首先先声明。本教程仅仅关于 OCX 打包 CAB 和 JS 调用 OCX。这里不探讨怎样通过 C++ 写 OCX。由于本人仅仅做 Java 开发。对于C++ 并没有研究。

    开发系统:win8.1 64位
    測试通过系统:win7 64 位、win8.1 64位、xp 32位

OCX 和 CAB 的关系。

    大家知道。得到 OCX 之后,假设想要调用,首先要注冊。

在不注冊的情况下。没办法调用 OCX 。

    最简单的注冊办法是手动注冊。手动注冊须要在命令行操作。对于开发者来说。多多少少要和命令行打交道。可能没有问题。只是对于使用我们系统的客户来说,让他进行命令行操作的确不合适。无论我们文档写得多么具体。对客户来说这都是不友好的,并且手动注冊也设计到安全性问题。

所以就须要在客户不知情的情况下自己主动对 OCX 注冊。

这也就是 CAB 的作用。

手动注冊 OCX

我们如果。OCX 所在的文件夹是:D:/ocx/xpbutton/xpbutton.ocx

 
     通过 regsvr32 xpbutton.ocx ,这样我们就手动注冊了 OCX。
     假设想卸载 OCX。我们能够反注冊:regsvr32 /u xpbutton.ocx 。
     注冊和卸载,我们都须要以管理员身份执行 cmd 控制台。-- 这里特别须要注意!
     假设在注冊时候出现以下的错误:
 
     1.首先查看是否以管理员身份执行 CMD。
     2.假设还是不行,能够考虑将对应的 OCX 放到系统文件夹下     
          a). 32 位系统放到 C:\Windows\System32
          b). 64 位系统放到 C:\Windows\SysWOW64
     3.假设还是报错。那能够确定是缺少 DLL 导致的。

各位能够下载一个工具:Dependency Walker。

    看这里的教程。看少了哪些 DLL。去网上下载这些 DLL,这些 DLL 就是你必需要和 OCX 一起打包到 CAB
压缩包里面去的。

由于你自己电脑少了,说明客户电脑也相同可能会少这些 DLL。

     这里须要注意的是:首选的是和你系统同样位数的 DLL,肯定不会错。实在找不到 64 位的,才考虑 32 位的版本号。
     下载了 DLL 后,将 DLL 存放到上面第二步提到的系统目录以下。然后再注冊。

OCX 打包 CAB

首先下载 OCX 打包签名工具:ocx 打包签名工具,  訪问password ddb4。


     将须要签名和打包的 OCX 和命令放到同样目录。


制作签名证书:

          在命令行执行以下命令:
         1. 运行命令:
makecert.exe -ss xpbutton -n "CN=这里随便" -sv .\xpbutton.pvk -r .\xpbutton.cer


 

输入三次,password。查看控制台出现 Succeeded 表示成功。

 

此时生成文件:xpbutton.cert 和 xpbutton.pvk

 
         2. 执行命令:
Cert2Spc.exe .\xpbutton.cer .\xpbutton.spc

          查看控制台,出现 Succeeded 表示成功。

 

此时会生成文件:xpbutton.spc


两条命令结束,我们一共得到三个文件:xpbutton.cer、xpbutton.pvk、xpbutton.spc

 

     对 OCX 进行签名

          打包 CAB 之前。首先须要对 OCX 本身进行签名操作,这一步非常重要。假设没做,你可能就犯错了。
          3. 执行命令:signtool signwizard








































































        假设想要填写时间戳,能够填写下面地址:http://timestamp.verisign.com/scripts/timstamp.dll





        等待片刻。出现以下提示,则表示对 ocx 签名完毕。

        控制台出现:Successfully completed signing wizard:<> 表示成功。

      编写 INF 文件

          INF 文件也是一个重点,假设编写错误,则不能正确打包。(各位能够下载本人编写的 INF 文件,在此基础上进行改动。保证 INF 文件的正确性)
          INF 參考文件下载地址:OCX inf 文件,  訪问password 49de。
       假设打包 CAB 没有问题 ocx 、dll 都会下载到 c:/windows/ocx/ 文件夹下,方便各位卸载 ocx ,删除 dll 文件。


[version]

signature="$CHICAGO$"

AdvancedINF=2.0



[DefaultInstall]

CopyFiles=files

RegisterOCXs=RegisterFiles



[DefaultUninstall]

cleanup=1

Delfiles=files

UnRegisterOCXs=RegisterFiles



[SourceDisksNames]

1 = %DiskName%, "xpbutton.cab", 1



[SourceDisksFiles]

xpbutton.ocx=1

msvcrtd.dll=1

mfc42d.dll=1

mfco42d.dll=1



[RegisterFiles]

%30%\Windows\ocx\xpbutton.ocx



[DestinationDirs]

files=30, Windows\ocx



[files]

xpbutton.ocx=xpbutton.ocx

msvcrtd.dll=msvcrtd.dll

mfc42d.dll=mfc42d.dll

mfco42d.dll=mfco42d.dll



[xpbutton.ocx]

file=thiscab

clsid={134EE1CC-4B8A-4E74-8C41-F4990065E2E1}

FileVersion=1,0,0,1

RegisterServer=yes



[msvcrtd.dll]

file=thiscab

FileVersion=6.0.8337.0



[mfc42d.dll]

file=thiscab

FileVersion=6.0.8168.0



[mcfo42d.dll]

file=thiscab

FileVersion=6.0.8267.0


[Strings]

DiskName="Windows\ocx"
        以上是本人的 inf 文件。解释几个部分。
           1.这里面加入了 3 个dll。假设各位不须要将 dll 打包到 cab ,则能够參照上面蓝色的部分。假设没有 mcfo42d.dll 则将蓝色的部分所有删除,其余的不动。

以此类推。

           2.

[xpbutton.ocx]
file=thiscab
clsid={134EE1CC-4B8A-4E74-8C41-F4990065E2E1}
FileVersion=1,0,0,1
RegisterServer=yes

进行简单解释:

              file=thiscab 照搬照抄,不解释。

因为是 64 位系统,本人測试这么写没问题。

              32 位系统也能够这样写: file-win32-x86=thiscab

              clsid 这里。最简单的办法是找到 ocx 的来源,询问制作 ocx 作者,他们知道这里应该填写什么。
              假设找不到制作人。也有办法。參照前文手动注冊 ocx ,然后查看搜索注冊表:xpbutton

           找到左边类似的注冊表结构,然后 134EE1CC-4B8A-4E74-8C41-F4990065E2E1 将是我们须要的 clsid 了。
           注意:本人在 C:\Windows\ocx\ 文件夹下注冊的 xpbutton.ocx 文件。所以上面右图地址才会是 C:\Windows\ocx\xpbutton.ocx 
           FileVersion 也是一样,最好的办法,找到 ocx 的来源(开发人员)。确定版本号号,编写 ocx 时,代码中会有 ocx 相应的版本号号。当初和 C 沟通时。看过 ocx 的 C++ 代码。里面有相应的版本号信息。这里的版本号信息必须和 OCX 的版本号信息一致。

RegisterServer=yes 表示下载下来后自己主动注冊此 ocx 。
           大家能够看到我以下的 dll 文件的代码中都没有这一句,意思是 dll 下载下来后不须要注冊,假设各位的 dll 也须要注冊,相应 dll 区域也须要加入此语句。

          3.对 INF 文件里绿色的部分进行解释
          绿色的部分,表示 dll 的版本,怎样确定 dll 版本。事实上非常easy。

          找到相应的 dll 右击,查看属性。这里的文件版本号,就是我们须要的版本号号,请注意。不是产品版本号。 

OCX 打包 CAB 文件

          4.执行命令:
CABARC.EXE -s 6144 n xpbutton.cab xpbutton.ocx xpbutton.inf
          须要解释一下这条命令:是将 xpbutton.ocx xpbutton.inf 文件打包成 xpbutton.cab 文件,假设我们须要将额外的 dll 也打包到 cab 里面。那这样写:CABARC.EXE -s 6144 n xpbutton.cab xpbutton.ocx msvcrtd.dll xpbutton.inf 以此类推。

对 CAB 文件签名

对 CAB 文件签名的过程,能够查看上文对 OCX 文件签名的过程,除了第一步此处选择的是 CAB 文件之外。其余步骤全然同样。


    到眼下为止,我们已经将 OCX 打包成 CAB 。可是到如今还不行。

非常多教程都到此为止。事实上 OCX 的繁琐远还没有结束。

JS 调用 OCX(CAB)

     引入 OCX 控件

          新建一个 HTML 文件,我们通过例如以下方式引入 OCX:

         一项一项解释:
         id="xpButton" 表示此 object 对象的 id 为 xpButton。命名随便都能够。兴许会用到。
         classid="clsid:134EE1CC-4B8A-4E74-8C41-F4990065E2E1" 看到这个,应该非常熟悉。classid="clsid:这部分照抄,不要修改。

仅仅修改冒号 : 后面部分即可了。(本人不小心把 clsid: 这一部分漏掉了,写成了 classid="134EE1CC-4B8A-4E74-8C41-F4990065E2E1",结果 CAB 文件下载不下来)。注意:千万别漏了 clsid。

         codebase="./xpbutton.cab#version=1,0,0,1" 这一部分代码是告诉浏览器,假设找不到 clsid 为 134EE1CC-4B8A-4E74-8C41-F4990065E2E1 注冊表,也就是系统中没有注冊过此 xpbutton.ocx 。则去找相应的 xpbutton.cab 文件。这里 "./xpbutton.cab" 意思是和当前 html 存放在同一文件夹下的
xpbutton.cab 文件。“./”表示当前路径,也就是 html 所在的路径。

后面的 "#version=1,0,0,1" 表示当前 OCX 的版本。也就是 CAB 压缩包中 INF 文件中面写的 OCX 的版本(FileVersion)。注意版本:1,0,0,1 是用逗号 "," 分隔。不是点号 "." ,假设你用了点号 "."。那么恭喜你,你又错了。

         补充说明:我们遇到过三个版本
                              1. OCX 编写时。C++ 代码中规定了 OCX 的版本。
                              2. OCX 打包 CAB 文件时,INF 文件里规定了当前 OCX 的版本。

                              3. HTML 调用 OCX 时,CODEBASE 表明了须要调用的 OCX 版本。
          这三个版本须要一致。
          非常有意思的是,假设想要升级 OCX,事实上非常easy,让 OCX 编写人员升级 OCX,然后我们升级 INF 文件里的版本,再把对应 HTML 中的版本也升级。浏览器调用此 HTML 时候,假设发现 CODEBASE 中的版本升级了。则会自己主动又一次下载 CAB 文件,并又一次注冊。

          之前。为了測试 OCX 升级后是否本身有问题,手动注冊此 OCX ,没有又一次打包 CAB,结果每次訪问都发现注冊的是 CAB 中上一个版本号的 OCX。说明仅仅要发现注冊过的 OCX 版本号和 CAB 版本号不一致的情况下,浏览器都会又一次下载 CAB,并又一次注冊。
             这里还要说明一点就是。OCX 被编写出来后。

clsid 就固定了。此 OCX 无论注冊到哪台电脑上,查看注冊表。clsid 都是一样的,不会改变。这也就是为什么我们在 HTML 里面,直接能够写上 clsid 的原因。由于客户下载 CAB ,自己主动注冊后,OCX 的 clsid 就是我们编写 C++ 时候规定的 clsid。

JS 调用 OCX 方法

          解释以上代码
          1. xpButton.AboutBox() ;
                    xpButton 事实上不是凭空出现的,这里的 xpButton 是 <object> 标签的 id。大家看上面的截图能够看到,<object id="xpButton">……</object>。
          2. xpButton.AboutBox() ;
                    AboutBox() 事实上是 OCX 中的一个方法。各位假设想要知道此 OCX 中有哪些方法,首选的是找 OCX 开发人员。在找不到的情况下,通过 tstcon32 软件,各位能够在这里下载: tstcon32 ActiveX 容器   訪问password 904d。假设不能使用,依据报错提示下载对应
DLL 就可以。

(研究 OCX 留下的后遗症。总认为某些软件会缺少 DLL )

          3. 为什么要 try catch
                    OCX 的繁琐和摸不着头脑,非常重要的原因是,即使调用失败它也不会报错。

所以。我们必需要在这里 try catch 手动弹出错误信息。但问题事实上也没有那么简单,即使是有报错信息,提示也让人摸不到头脑。

                    注意,各位一定要记得 try catch,不然不论什么错误都不会有提示。
                    以下总结一下本人遇到的报错信息与真实原因的相应关系,以防止各位各种百度、Google 最后找到的是错误的解决方式。
                    OCX 报错,普通情况下,都是本机測试通过后,部署到server或者使用其它人的电脑,发现调用失败。

                    1. [object Error]、Error:找不到成员

                    假设是遇到上面的报错:[object Error] 、Error:找不到成员
                    1.首先确定 C:\Windows\ocx 文件夹下是否有下载的 OCX 文件(假设各位下载了本教程中的 INF 文件,则到C:\Windows\ocx 文件夹下去找),假设该文件夹下没有不论什么文件或者没有该文件夹,则就对比上文。查看是否是 INF 文件编写有问题,或者是 HTML 引入 OCX 对象有错误,导致下载失败。
                    2.假设 OCX 文件已下载,则表示尽管 CAB 文件没问题。但 OCX 未注冊或者说是注冊失败。注冊失败的原因,我们首先须要确认是否是缺少 DLL 。怎样确认。能够使用上文提到的 Dependency Walker 软件。假设发现确实是少了 DLL,那我们应该又一次打包 CAB。将所缺少的 DLL 文件一起打包到 CAB 中。非常多时候,我们通过 CAB 自己主动注冊 OCX
,大多数情况下是不会报不论什么的错误的。即使是由于缺少 DLL 没有注冊成功。也没有不论什么提示。本人在非常多电脑上測试的结果是,仅仅有一台 Win7,出现了缺少 DLL 的报错示,其它全部电脑都没有不论什么的错误提示。这里特别须要注意:打包 CAB 文件后,请用多台电脑进行測试,最好測试不同的系统。也尽量能够挑选公司非开发人员的电脑。

千万别在自己电脑上測试通过,或者某些 OCX 开发人员电脑上測试通过后便觉得其没有问题。


                    2. 对象不支持此属性或方法
                    这个错误。在开发的过程中,是必定会遇到的。刚開始,一直以为是调用方式有问题。在尝试了网上能找到的全部其它不同调用方式后发现。并不是如此。假设能保证 OCX 的正确性的前提下,此问题的根本原因是由于浏览器对于 OCX 不信任。拦截了 OCX 里面的方法调用。

解决此问题的根本办法是改动浏览器设置。

                         3.改动浏览器安全设置
                     网上能够找到非常多浏览器的改动点,事实上大部分不须要改动,改动了反而减少了安全性,添加风险。




                         反选“对该区域中的全部网站要求server验证(https)”,填上server地址,比如:http://192.168.0.61 然后加入,加入完毕后,再次勾选"对该区域中的全部网站要求server验证(https)"。这一步的操作是保证浏览器信任此网站。





                         此处改动信任网站的安全性级别,将图上的两个,由原来的禁止,改动为提示或者启用。

                         事实上在首次訪问 CAB 网页前,我们就应该先改动浏览器安全性策略,改动完毕后再訪问,一般都不会出现什么问题。


至此,OCX 的相关知识已经所有介绍完成,此教程应该能够帮助大家少走一些弯路。这也是近期两个星期的研究成果。

        2015.08.26 补充

1.注意:假设使用了 Java 开发,后台使用了 Spring。则应该在 Web.xml 中加入以下的代码。

  <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.cab</url-pattern>
</servlet-mapping>

上面代码告诉 Spring 不要拦截 *.cab 静态文件。



        2.JSP 引入 CAB 文件

 <div style="display:none;">
<object id="readcardOCX" width=400 height=100
classid="clsid:F6F2B22E-FC89-489F-967B-9676EB269F55"
CODEBASE= "${pageContext.request.contextPath}/cab/readcard.cab#version=1,0,0,1"
></object>
</div>

在project中引入 CAB 文件,我们须要写

CODEBASE= "${pageContext.request.contextPath}/cab/readcard.cab#version=1,0,0,1"

${pageContext.request.contextPath} 表示project名

       cab 文件存放在 webapp/cab 以下

OCX 打包 CAB 与 JS 调用具体教程的更多相关文章

  1. webpack入门之打包html,css,js,img(一)

    webpack到底是什么,网上一大堆介绍的东西,越看越不知道说的什么,所以今天打算自己来记录一下这段时间学习webpack的成果, webpack就是打包文件用的,html,css,js,img,为什 ...

  2. vs2010开发activex(MFC)控件/ie插件(三),js调用ocx控件的接口函数

    原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/50802280   js调用ocx控件的接口函数,先看demo效果:      简单测试过程 ...

  3. MFC Activex 开发、ocx打包成cab、部署、测试、自动升级

    小小抱怨下:也许是MFC现在用的人少的缘故.在国内和国外都基本上找不到什么全的资料.特别是ocx打包成Cab时的安装文件inf的编写方面,国内基本上是copy,抄的还一知半解.查找个资源真心的累啊.现 ...

  4. JS调用Delphi编写的OCX控件

    原文:http://www.mamicode.com/info-detail-471283.html 一.使用Delphi XE2编写OCX控件 生成OCX工程: 1.File-New-Other,在 ...

  5. 【FLEX教程】#007 如何让JS调用SWF里的方法

    HTML中,JS如何调用SWF里面已经封装好的代码呢? 有一些事情Flex没办法实现的,需要通过调用JS来实现. eg: 当浏览器窗体关闭的时候,弹出一个对话框,提示用户是否退出?或者是否保存当前的操 ...

  6. Phonegap 之 iOS银联在线支付(js调用ios端银联支付控件)

    Phonegap项目,做支付的时候,当把网站打包到ios或android端成app后,在app上通过wap调用银联在线存在一个问题: 就是当从银联支付成功后,再从服务器返回到app客户端就很难实现. ...

  7. FLASH CC 2015 CANVAS (二)html中写JS调用flash中的元件、函数、变量

    注意 此贴 为个人边“开荒”边写,所以不保证就是最佳做法,也难免有错误! 正式教程会在后续开始更新 当你导出第一个canvas后,你会在保存fla的文件夹里 (每个项目默认位置)看到 如下文件,(请先 ...

  8. Xilium.CefGlue利用XHR实现Js调用c#方法

    防外链 博客园原文地址在这里http://www.cnblogs.com/shen6041/p/3442499.html 引 Xilium CefGlue是个不错的cef扩展工程,托管地址在这里 ht ...

  9. PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码

    PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码 看看新闻网>看引擎>开源产品 0人收藏此文章, 发表于8小时前(2013-09-06 00:39) ...

随机推荐

  1. 为什么字符串类型可以调用构造函数String的方法,却又不是它的实例

    从所周知,在js中定义一个字符串我们有两种办法: var a = new String("a"); var a = "a"; 第一种方法使用构造函数创建,作为S ...

  2. Flask Web 发送邮件单文件

    import os from flask import Flask, render_template, session, redirect, url_for from flask_script imp ...

  3. 微信关于网页授权access_token和普通access_token的区别

    微信官网网址:https://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html#.E9.99.84.EF.BC.9A.E6. ...

  4. Fiddler——抓包工具的使用

    fiddler安装 pc端安装fiddler,自行从百度下载即可 Fiddler是强大且好用的Web调试工具之一,它能记录客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输 ...

  5. (转)Hibernate框架基础——映射主键属性

    http://blog.csdn.net/yerenyuan_pku/article/details/52740744 本文我们学习映射文件中的主键属性,废话不多说,直接开干. 我们首先在cn.itc ...

  6. blender--(凹凸贴图)................https://jingyan.baidu.com/article/9f63fb917c4becc8400f0ea8.html

    在blender中直接绘制模型凹凸纹理细节 听语音 | 浏览:32 | 更新:2018-02-20 11:18 1 2 3 4 5 6 7 分步阅读 在blender中为了表现更多的模型细节,我们会常 ...

  7. PS切图基本操作

    PS切图基本操作 2016-05-11 20:56:46|  分类: PhotoShop|字号 订阅     下载LOFTER我的照片书  |     1首先在“文件”中打开一张图片.   2点击“移 ...

  8. type、object、class之间的关系

    class Foo: pass print(type(int)) # <class 'type'> print(type(str)) # <class 'type'> prin ...

  9. Redis多实例配置以及主从同步

    一.多实例配置 1.准备俩配置文件,开两个就准备两个 redis-6380.conf redis-6381.conf 2.分别写入配置信息(这里简化了配置) # 运行在6380端口 bind 172. ...

  10. idea搭建maven项目 【转发】

    为了创建maven项目可是花了我时间了,网上的教程跟我的实际情况不符合,尤其是facets .artifacts 那块.幸亏找到这篇文章没解决了我的问题,他的描述跟我的情况一模一样.这篇文章竟然来自百 ...