闫某人的博客

 

C# ActiveX开发部署更新

 

说到ActiveX,首先需要了解OLEComActivex之间的关系,下面是从一个百度知道中搜索到的结果,

 

关于三个概念:ActiveX、OLE和COM   

         熟悉面向对象编程和网络编程的人一定对ActiveX、OLE和COM/DCOM这些概念不会陌生,但是它们之间究竟是什么样的关系,对许多们还是比较模糊的。在具体介绍它们的关系之间,我们还是先明确组件(Component)和对象(Object)之间的区别。组件是一个可重用的模块,它是由一组处理过程、数据封装和用户接口组成的业务对象(Rules object)。组件看起来像对象,但不符合对象的学术定义。它们的主要区别是:1)组件可以在另一个称为容器(有时也称为承载者或宿主)的应用程序中使用,也可以作为独立过程使用;2)组件可以由一个类构成,也可以由多个类组成,或者是一个完整的应用程序;3)组件为模块重用,而对象为代码重用。现在,比较流行的组件模型有COM(Component Objiect Module,对象组件模型)/DCOM(Distributed COM,分布式对象组件模型)和CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)。到这里,已经出现了与本文相关的主题COM,而CORBA与本文无关,就不作介绍。之所以从组件与对象的区别说起,是想让大家明确COM和CORBA是处在整个体系结构的最底层    

        如果暂时对此还不能理解,不妨继续往下看,最后在回过头看一看就自然明白了。现在开始阐述ActiveX、OLE和COM的关系。首先,让大家有一个总体的概念,从时间的角度讲,OLE是最早出现的,然后是COM和ActiveX;从体系结构角度讲,OLE和ActiveX是建立在COM之上的,所以COM是基础;单从名称角度讲,OLE、ActiveX是两个商标名称,而COM则是一个纯技术名词,这也是大家更多的听说ActiveX和OLE的原因。既然OLE是最早出现的,那么就从OLE说起,自从Windows操作系统流行以来,“剪贴板”(Clipboard)首先解决了不同程序间的通信问题(由剪贴板作为数据交换中心,进行复制、粘贴的操作),但是剪贴板传递的都是“死”数据,应用程序开发者得自行编写、解析数据格式的代码,于是动态数据交换(Dynamic Data Exchange,DDE)的通信协定应运而生,它可以让应用程序之间自动获取彼此的最新数据,但是,解决彼此之间的“数据格式”转换仍然是程序员沉重的负担。对象的链接与嵌入(Object Linking and Embedded,OLE)的诞生把原来应用程序的数据交换提高到“对象交换”,这样程序间不但获得数据也同样获得彼此的应用程序对象,并且可以直接使用彼此的数据内容,其实OLE是Microsoft的复合文档技术,它的最初版本只是瞄准复合文档,但在后续版本OLE2中,导入了COM。由此可见,COM是应OLE的需求而诞生的,所以虽然COM是OLE的基础,但OLE的产生却在COM之前。COM的基本出发点是,让某个软件通过一个通用的机构为另一个软件提供服务。COM是应OLE的需求而诞生,但它的第一个使用者却是OLE2,所以COM与复合文档间并没有多大的关系,实际上,后来COM就作为与复合文档完全无关的技术,开始被广泛应用。这样一来,Microsoft就开始“染指”通用平台技术。但是COM并不是产品,它需要一个商标名称。而那时Microsoft的市场专家们已经选用了OLE作为商标名称,所以使用COM技术的都开始贴上了OLE的标签。虽然这些技术中的绝大多数与复合文档没有关系。Microsoft的这一做法让人产生这样一个误解OLE是仅指复合文档呢?还是不单单指复合文档?其实OLE是COM的商标名称,自然不仅仅指复合文档。但Microsoft自己恐怕无法解释清楚,这要花费相当的精力和时间。于是,随着Internet的发展,在1996年春,Microsoft改变了主意,选择ActiveX作为新的商标名称。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然,ActiveX最核心的技术还是COM。ActiveX和OLE的最大不同在于,OLE针对的是桌面上应用软件和文件之间的集成,而ActiveX则以提供进一步的网络应用与用户交互为主。到这里,大家应该对ActiveX、OLE和COM三者的关系有了一个比较明确的认识,COM才是最根本的核心技术,所以下面的重点COM。让对象模型完全独立于编程语言,这是一个非常新奇的思想。这一点从C++和Java的对象概念上,我们就能有所了解。但所谓COM对象究竟是什么呢?为了便于理解,可以把COM看作是某种(软件)打包技术,即把它看作是软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和以组支持库。COM对象可以用C++、Java和VB等任意一种语言编写,并可以用DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的浏览器,无需关心对象是用什么语言写的,也无须关心它是以DLL还是以另外的过程来执行的。从浏览器端看,无任何区别。这样一个通用的处理技巧非常有用。例如,由用户协调运行的两个应用,可以将它们的共同作业部分作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行从Web服务器下载的代码,浏览器可把它看作是COM对象,也就是说,COM技术也是一种打包可下载代码的标准方法(ActiveX控件就是执行这种功能的)。甚至连应用与本机OS进行交互的方法也可以用COM来指定,例如在Windows和Windows

NT中用的是新API,多数是作为COM对象来定义的。可见,COM虽然起源于复合文档,但却可有效地适用于许多软件问题,它毕竟是处在底层的基础技术。用一句话来说,COM是独立于语言的组件体系结构,可以让组件间相互通信。随着计算机网络的发展,COM进一步发展为分布式组件对象模型,这就是DCOM,它类似于CORBA的ORB,本文对此将不再做进一步的阐述。通过上面的讲述相信大家一定对ActiveX、OLE和COM/DCOM的关系有了一个清楚的了解。   

 

     有了上面的了解,下面我们开始新作一个Activex控件,并将其发布到网站中。注意,在此我们只用C#实现。

  1. 首先我们先新建一个控件类库,命名为OCXOne
  2. 用微软自带的GUID生成器生成一个新的GUID来为控件指定ID(以后在网站的使用中,就是通过这个GUID来找到你注册的组件的),并设置ComVisible属性,如下:

    

1[Guid("CAEE6D0D-AE50-4d2d-AAB4-806736FB549F")]
2
3[ComVisible(true)]
4
5 public partial class UCAccountMain : DevExpress.XtraEditors.XtraUserControl, IObjectSafety
6
7{………… }

3. 注意到步骤2中需要继承IObjectSafety接口,这时在项目中添加一个IObjectSafety接口,(在使用的过程中直接拷贝即可,尤其是GUID不要改动)具体如下:

 

Code

 

4. 下面是控件对接口的实施,在使用的时候也是直接copy即可。控件之所以要实现这个接口是因为浏览器中默认情况下是不允许OCXscript进行交互,实现这个接口后,浏览器会允许交互。

       

Code

5. 此时你可以实现自己的控件了,在这里我们只简单的实现一个方法,注意必须要未方法添加两个Attribute

       

1[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
2
3        public void InitialWC(string mess)
4
5        {            MessageBox.Show(mess);        }
6
7

6. 现在控件写完了,可是需要怎样调用呢,而且还要保证自动更新,这时需要在解决方案中添加一个setup项目,命名为UCOneSetUp,并设置主输出为我们刚刚开发的类库,同时选中setup项目并按F4,在这里将RemovePreviousVersions属性设置未True. 然后设置主输出的属性,需要将Register属性设置为vsdrpCOM(这个属性是表示在安装后,安装程序自动为你的主输出注册成com),然后生成整个项目。

  1. 现在随便找个地方新建一个文件夹,(不需要在项目中添加,其他地方也可以),添加UCOne.INFUCOne.bat,并将刚刚生成的UCOneSetUp.msi拷贝到此文件夹,并将微软制作CAB的工具CabArc.Exe也拷贝到这个目录,下面右键打开UCOne.INF,输入以下信息

[version] 

signature
="$CHICAGO$"

AdvancedINF
=2.0  

 

[Setup Hooks]

hook1
=hook1

 

[hook1]

run= msiexec /i %EXTRACT_DIR%\UCOneSetUp.msi /qn

打开bat,编辑内容如下:

cabarc n UCOneOCX.CAB UCOne.inf UCOneSetUp.msi

然后执行这个批处理,会生成 UCOneOCX.CAB

  1. 现在向解决方案中在添加一个web项目,新建一个页面用来展示你的ocx,此处命名为HellOCX.aspx,并到后台代码中添加一个方法GetMess()(因为后面我们需要调用这个方法实现OCXbs的交互),最后将刚刚生成的UCOneOCX.CAB添加到web项目中,并与HellOCX.aspx同级(可以不同级,这里是通过相对路径来下载CAB文件的)打开aspx源设计,代码如下:
  1. Code
    现在用浏览器浏览可能达不到预期的效果,这里主要是因为浏览器的权限设置所致。解决办法如下,首先我们更改可信站点的设置,将其中余
    ActiveX有关的项设置成允许或者提示。
  2. 现在用浏览器浏览,即可看到效果。
  3. 不过事情到这里还不算完美,因为没有自动更新的支持会是你的项目非常的难于维护和实施。实现自动更新分成三个步骤,

第一,改变控件的GUID

第二,提升setup的版本号

第三,改变aspxGuiD,已保证和控件的GUID一致,这样之所以能够实现自动更新,是因为现在aspx根据新指定的GUID已经不能找到指定的COM,这时会自动根据codebase中的内容去下载新的CAB,其实我们的CAB就是包装了SetUp,而且serup中我们设置RemovePreviousVersionTrue,则再次安装的时候,他会首先将以前的版本删除,然后在装最新版本,通过这种方式我们实现了自动更新。

posted on 2008-12-04 10:00  ArthurYan  阅读(4960)  评论(3编辑  收藏  举报

导航