C#开发ActiveX控件及制作CAB包
2010-09-29 15:00
495 查看
一个项目要用到ActiveX控件,参照网上众多的例子,ActiveX控件倒是很容易就搞出来了;
然后做了一个【安装项目】,倒是可以使用,只不过需要在客户端手动点击安装,下一步,下一步…觉得不是很爽;
又试了试【CAB项目】,好像没人用VS2008来做,费了点功夫,终于找到解决办法。
特将此经验与大家分享。
开发工具:VisualStudio2008
.NET版本:2.0
开发语言:C#
一、编写ActiveX控件
1、新建一个【Windows窗体控件库项目】
2、添加一个【用户控件】
3、拖两个Label控件到界面上
4、为控件添加一个方法,用来设置在Label中显示当前时间
查看源代码
打印
?
5、新建一个接口:
据说实现该接口的目的就是提高程序的安全性,以便客户端IE在不更改设置的情况下可以预行该ActiveX控件。
关于这个有篇文章,推荐大家看看:
http://blog.csdn.net/optman/archive/2007/07/18/1698070.aspx
查看源代码
打印
?
6、让我们的控件实现这个接口
关于实现这个接口,篇幅较长,可以在这篇文章找到:
http://www.pinvoke.net/default.aspx/Interfaces/IObjectSafety.html
7、为我们的控件添加Guid、ProgId和ComVisible属性
查看源代码
打印
?
8、打开项目属性,在生成里边,勾选【为Com互操作注册】
9、生成项目,进入到bin/Release目录下可以看到
HelloBossma.dll
HelloBossma.tlb
这两个文件时必须的,否则生成不成功。
二、制作ActiveXSetup安装文件
1、新建一个安装项目
2、在项目上点右键,【添加】->【项目输出】,选择上边的项目
3、打开安装项目的属性页面,设置安装URL
这里设置为:http://localhost/hellobossma
这个目录必须是实际存在的,用来存放生成的安装文件,供客户端下载安装。
4、生成项目
会生成两个文件,一个exe文件和一个msi文件
5、新建一个网站,添加如下代码到网页中。
其中classid即为控件的Guid。
查看源代码
打印
?
解压这个文件,里边有详细的使用说明。
6、将安装项目生成的exe和msi文件拷贝到网站hellobossma目录中。
HelloBossmaSetup.msi
setup.exe
7、启动网站,确保访问setup.exe的目录与【安装项目】中的【安装URL】一致。
8、一般情况下,网页会弹出提示,是否安装ActiveX控件等,如果提示了也不能安装,需要将网站添加到信任站点,并允许下载不安全和未签名控件。关于控件的签名和认证,本文不做说明,需要的请自行搜索。
使用这种安装方法,会在客户端弹出安装软件的界面,对客户来说,不太友好。
三、制作ActiveXCAB安装包
尝试了VS中的【CAB项目】模板,但是不幸的是,控件怎么也安装不上,放弃。
在网上看到很多人使用CABARC.EXE,试了一下,居然成功了,特将过程记录下来。
1、下载这个程序包,可以从微软下载,地址:
2、【开始】-【运行】,输入“CMD”,在打开的命令提示符界面中,进入解压后文件的BIN目录,
这里需要加入两个文件:
HelloBossmaSetup.msi
install.inf
HelloBossmaSetup.msi是上边的安装项目生成的安装程序。
install.inf是一个文本文件,指定运行控件所需要下载或者呈交的文件。
关于inf文件的书写规范,这里不做介绍,有需要的可以自己搜一下。
这个例子中install.inf文件的内容
查看源代码
打印
?
有了这两个文件,运行下边的命令,成功的话会在当前目录生成HelloBossma.cab文件。
3、把这个文件放到控件下载目录中,然后修改网页中的调用方式。
查看源代码
打印
?
这里还添加了一个按钮,点击时触发一个事件,调用控件的显示时间方法,点击按钮,你会发现控件上时间的变化。
OK,这篇文章到这里正文就结束了。
只是简单了解下使用C#开发ActiveX控件,很多东西还没弄清楚,有问题的话,欢迎提出来。
1、开发及测试环境:
(1)开发环境:
VisualStudio2008SP1
cabsdk(下载地址:http://support.microsoft.com/kb/310618
)
(2)测试环境:
WindowsServer2003R2SP2
IE6
2、创建项目
我这里创建了三个项目:
(1)HelloBossma:
项目模板:Windows窗体控件库
(2)HelloBossmaSetup:
项目模板:安装项目
(3)Web:
项目模板:ASP.NET网站
3、HelloBossma项目
这个项目用于编写具体的控件,并生成安装文件所需要的dll。
(1)添加用户控件:
(2)设计控件:
添加Panel、GroupBox、Label控件。NowTime是一个Label控件,用于显示时间。
然后在控件对应的代码文件中编写程序:
查看源代码
打印
?
关于IObjectSafety的实现参考了:http://www.pinvoke.net/default.aspx/Interfaces/IObjectSafety.html
查看源代码
打印
?
这里还包含了一个可以被外部调用的方法,传进来一个字符参数,并显示出来:
查看源代码
打印
?
(3)设置生成属性,勾选:为Com互操作注册
(4)生成项目,生成这两个文件:
HelloBossma.dll
HelloBossma.tlb
是必须的,否则生成不成功。
4、HelloBossmaSetup项目
这是一个安装项目,用来生成安装程序。
(1)在项目上点右键,【添加】->【项目输出】,选择上边的HelloBossma项目
(2)在安装项目上点右键,属性
安装URL:貌似用于查找应用程序更新,具体看:http://msdn.microsoft.com/zh-cn/library/c37e68bc(VS.90).aspx
这个目录最好是实际存在的,用来存放生成的安装文件,供客户端下载安装。没有的话就随便输入一个吧。
(3)添加卸载程序
拷贝文件C:/Windows/System32/msiexec.exe文件,修改文件名为Uninstall.exe,添加到安装项目中,然后创建一个快捷方式。
在【用户的“程序”菜单下边】添加一个文件夹HelloBossma,将快捷方式拖动到这里边。
在卸载控件上点击右键,属性:
设置Arguments,就是指定要卸载的程序,后面的ProductCode可以这样获得:
选中项目,然后鼠标放到右侧的“属性”上,就可以看到ProductCode了:
(4)最后生成项目
5、制作CAB文件
(1)为了方便操作,可以将CABARC.EXE添加到环境变量中:桌面上右击“我的电脑”,“属性”,“高级”,“环境变量”,“系统变量”,找到“Path”,在后边把CABARC.EXE所在的路径添加上去,注意用分号隔开新添加的路径。
(2)准备好文件
install.inf:CAB安装配置文件
HelloBossmaSetup.msi:安装程序文件
install.inf文件的内容:
查看源代码
打印
?
run:一般只需要修改这个就行了
(3)执行cabarc命令
桌面左下角“开始”,“运行”,输入cmd,打开命令提示符工具,进入准备好的文件的目录,执行命令:
cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.inf
显示“Completedsuccessfully”,打开所在目录,就可以看到生成的文件了。
6、部署到网站
在网站中新建一个目录hellobossma,将生成的cab文件拷贝到里边。
新建一个网页,将控件添加到页面:
查看源代码
打印
?
ActiveX控件作为一个object添加到页面中,其classid是在编写HelloBossmaActiveX类时定义好的Guid值,codebase用来指示cab安装文件的路径,还可以设置宽度、高度。另外其中文字受页面中字体样式的影响。
因为我们的ActiveX控件没有签名,所以将测试站点加到“本地Intranet”中或者“可信站点”中,并设置安全级别为“低”。
然后打开浏览器,提示安装,点击“安装”,稍等下,效果就出来了:
点击按钮,就可以通过javascript设置ActiveX控件中的时间了。
Over!
这篇文章是一个简单的例子,没有进行更广范围平台的测试,后续文章会逐渐加入。
1、方法一
(1)在VS项目中添加Com对象引用:MicrosoftHtmlObjectLibrary(mshtml.tlb)
(2)ActiveX中公开一个方法,传递window对象到ActiveX中
ActiveX中公开一个方法,接受传递进来的参数
查看源代码
打印
?
在页面中调用ActiveX的公开方法,传递当前window对象进去:
查看源代码
打印
?
(3)在ActiveX控件中添加一个按钮,当点击这个按钮时,触发页面中的javascript。
点击按钮的方法:
查看源代码
打印
?
现在卸载掉原来的ActiveX控件,安装新的控件,打开页面,点击按钮,看到如下效果,说明成功。
调用javascript时还可以传递参数,这里不做演示了,自己可以试一下。
参考:http://www.cnblogs.com/liubiqu/articles/92632.html
2、方法二
(1)在VS项目中添加Com对象引用:MicrosoftHtmlObjectLibrary(mshtml.tlb)
和第一种方法相同。
(2)用c#实现两个COM类,IOleClientSite和IOleContainer
查看源代码
打印
?
(3)在ActiveX中编写CallJavascript方法:
查看源代码
打印
?
点击按钮时的操作:
查看源代码
打印
?
(4)网页中的javascript
查看源代码
打印
?
卸载原来的ActiveX控件,重新安装,实际效果:
1、更新Activex的版本:
(1)在ActiveX项目上点右键,属性,应用程序,程序集信息,最初的版本是1.0.0.0,修改为1.0.1.0
(2)修改控件,以区别1.0.0.0版本,修改V1.0.0为V1.0.1
(3)然后重新生成。
2、修改安装程序
(1)添加注册表项
在项目上点右键,视图,注册表:
在HKEY_CLASSES_ROOT下创建CLSID/{ActiveX的GUID}/InstalledVersion/,
在InstalledVersion下新建字符串值,修改字符串的值为”1,0,1,0″,
注意:删除名称中的值,自动会显示“(默认值)”,这样才能设置注册表中默认值,不要自己输入“默认值”。
(2)修改安装程序版本
修改Version为”1.0.1″,修改RemovePreviousVersions为”True”。
(3)重新生成安装程序
3、重新制作CAB安装包
cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.inf
4、修改网站
(1)将生成的CAB安装包替换原来的安装包。
(2)修改页面控件版本
查看源代码
打印
?
5、最终效果
刷新页面,提示安装新的版本,直接安装就好了。
1、测试环境:Windows7+IE8
2、修改之前,直接访问页面看看,发现出错了:
出错行:document.HelloBossma.SetTime(vYear+“-”+vMon+“-”+vDay+””+vHour+“:”+vMin+“:”+vSec)
然后到控制面中没有找到安装的ActiveX程序,结合出错行,大致得出结论:ActiveX没有安装成功!
3、修改文件
install.inf:
查看源代码
打印
?
新加[Deployment],关于这个项目看:http://msdn.microsoft.com/zh-cn/library/dd433049(en-us,VS.85).aspx
InstallScope=machine我这里只能用这个,改成user无法安装成功,原因未知。
另外在vista以后的版本只能执行cab中的文件了,所以msiexec转移到了bat中执行,添加一个bat文件。
run.bat:
查看源代码
打印
?
4、制作CAB包
重新制作CAB包,添加一个run.bat:
查看源代码
打印
?
5、在浏览器安装
输入网址,提示安装,然后出现命令运行框,然后消失。
如果安装成功,会出现控件界面。
6、一个兼容性问题
这时候会发现,浏览器左下角有javascript错误,同时点击CallJavascript发生异常。
无法将类型为“Systerm._ComObject”的COM对象强制转换为类类型“mshtml.HTMLWindow2Class”。
在XP、WindowsServer2003中都没有问题,Windows7上出现问题,可能是权限设置问题。
按照上边的提示,找到出现问题的地方:
Default.aspx:
查看源代码
打印
?
HelloBossmaActiveX.cs
查看源代码
打印
?
按照提示,我们可以把它转换为接口试试,在网上找到了HTMLWindow2Class的定义,
查看源代码
打印
?
经过测试,IHTMLWindow2定义了execScript,所以修改SetHtml为:
查看源代码
打印
?
如果你需要其它的方法,换换接口试试。
重新编译,重新安装控件,OK了!
然后做了一个【安装项目】,倒是可以使用,只不过需要在客户端手动点击安装,下一步,下一步…觉得不是很爽;
又试了试【CAB项目】,好像没人用VS2008来做,费了点功夫,终于找到解决办法。
特将此经验与大家分享。
开发工具:VisualStudio2008
.NET版本:2.0
开发语言:C#
一、编写ActiveX控件
1、新建一个【Windows窗体控件库项目】
2、添加一个【用户控件】
3、拖两个Label控件到界面上
4、为控件添加一个方法,用来设置在Label中显示当前时间
//设置当前时间 |
public void SetTime( string timeStr) |
{ |
this .label2.Text=timeStr; |
} |
据说实现该接口的目的就是提高程序的安全性,以便客户端IE在不更改设置的情况下可以预行该ActiveX控件。
关于这个有篇文章,推荐大家看看:
using System; |
using System.Collections.Generic; |
using System.Text; |
using System.Runtime.InteropServices; |
namespace HelloBossma |
{ |
[ComImport,GuidAttribute( "CB5BDC81-93C1-11CF-8F20-00805F2CD064" )] |
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] |
public interface IObjectSafety |
{ |
[PreserveSig] |
int GetInterfaceSafetyOptions( ref Guidriid,[MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions,[MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); |
[PreserveSig()] |
int SetInterfaceSafetyOptions( ref Guidriid,[MarshalAs(UnmanagedType.U4)] int dwOptionSetMask,[MarshalAs(UnmanagedType.U4)] int dwEnabledOptions); |
} |
} |
关于实现这个接口,篇幅较长,可以在这篇文章找到:
7、为我们的控件添加Guid、ProgId和ComVisible属性
namespace HelloBossma |
{ |
[Guid( "636B8CE1-7512-464C-B63C-FC75BDCA21DB" ),ProgId( "HelloBossma.HelloBossmaActiveX" ),ComVisible( true )] |
public partial class HelloBossmaActiveX:UserControl,IObjectSafety |
{ |
... |
} |
} |
9、生成项目,进入到bin/Release目录下可以看到
HelloBossma.dll
HelloBossma.tlb
这两个文件时必须的,否则生成不成功。
二、制作ActiveXSetup安装文件
1、新建一个安装项目
2、在项目上点右键,【添加】->【项目输出】,选择上边的项目
3、打开安装项目的属性页面,设置安装URL
这里设置为:http://localhost/hellobossma
这个目录必须是实际存在的,用来存放生成的安装文件,供客户端下载安装。
4、生成项目
会生成两个文件,一个exe文件和一个msi文件
5、新建一个网站,添加如下代码到网页中。
其中classid即为控件的Guid。
< object classid = "clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB" codebase = "hellobossma/setup.exe" width = "442" height = "49" id = "helloBossma" ></ object > |
6、将安装项目生成的exe和msi文件拷贝到网站hellobossma目录中。
HelloBossmaSetup.msi
setup.exe
7、启动网站,确保访问setup.exe的目录与【安装项目】中的【安装URL】一致。
8、一般情况下,网页会弹出提示,是否安装ActiveX控件等,如果提示了也不能安装,需要将网站添加到信任站点,并允许下载不安全和未签名控件。关于控件的签名和认证,本文不做说明,需要的请自行搜索。
使用这种安装方法,会在客户端弹出安装软件的界面,对客户来说,不太友好。
三、制作ActiveXCAB安装包
尝试了VS中的【CAB项目】模板,但是不幸的是,控件怎么也安装不上,放弃。
在网上看到很多人使用CABARC.EXE,试了一下,居然成功了,特将过程记录下来。
1、下载这个程序包,可以从微软下载,地址:
2、【开始】-【运行】,输入“CMD”,在打开的命令提示符界面中,进入解压后文件的BIN目录,
这里需要加入两个文件:
HelloBossmaSetup.msi
install.inf
HelloBossmaSetup.msi是上边的安装项目生成的安装程序。
install.inf是一个文本文件,指定运行控件所需要下载或者呈交的文件。
关于inf文件的书写规范,这里不做介绍,有需要的可以自己搜一下。
这个例子中install.inf文件的内容
[version] |
signature="$CHICAGO$" |
AdvancedINF=2.0 |
[SetupHooks] |
hook1=hook1 |
[hook1] |
run=msiexec.exe/i"%EXTRACT_DIR%/HelloBossmaSetup.msi"/qn |
3、把这个文件放到控件下载目录中,然后修改网页中的调用方式。
< object classid = "clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB" codebase = "hellobossma/HelloBossma.CAB" width = "442" height = "49" id = "helloBossma" > |
</ object >< input onclick = "helloBossma.SetTime((newDate()).getTime())" type = "button" value = "Click" /> |
OK,这篇文章到这里正文就结束了。
只是简单了解下使用C#开发ActiveX控件,很多东西还没弄清楚,有问题的话,欢迎提出来。
1、开发及测试环境:
(1)开发环境:
VisualStudio2008SP1
cabsdk(下载地址:
)
(2)测试环境:
WindowsServer2003R2SP2
IE6
2、创建项目
我这里创建了三个项目:
(1)HelloBossma:
项目模板:Windows窗体控件库
(2)HelloBossmaSetup:
项目模板:安装项目
(3)Web:
项目模板:ASP.NET网站
3、HelloBossma项目
这个项目用于编写具体的控件,并生成安装文件所需要的dll。
(1)添加用户控件:
(2)设计控件:
添加Panel、GroupBox、Label控件。NowTime是一个Label控件,用于显示时间。
然后在控件对应的代码文件中编写程序:
using System; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Drawing; |
using System.Data; |
using System.Text; |
using System.Windows.Forms; |
using System.Runtime.InteropServices; |
namespace HelloBossma |
{ |
///<summary> |
///Guid将用作控件的classid |
///IObjectSafety的是用来标记可安全执行脚本的ActiveX控件 |
///</summary> |
[Guid( "636B8CE1-7512-464C-B63C-FC75BDCA21DB" ),ProgId( "HelloBossma.HelloBossmaActiveX" ),ComVisible( true )] |
public partial class HelloBossmaActiveX:UserControl,IObjectSafety |
{ |
private const string _IID_IDispatch= "{00020400-0000-0000-C000-000000000046}" ; |
private const string _IID_IDispatchEx= "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}" ; |
private const string _IID_IPersistStorage= "{0000010A-0000-0000-C000-000000000046}" ; |
private const string _IID_IPersistStream= "{00000109-0000-0000-C000-000000000046}" ; |
private const string _IID_IPersistPropertyBag= "{37D84F60-42CB-11CE-8135-00AA004BB851}" ; |
private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER=0x00000001; |
private const int INTERFACESAFE_FOR_UNTRUSTED_DATA=0x00000002; |
private const int S_OK=0; |
private const int E_FAIL= unchecked (( int )0x80004005); |
private const int E_NOINTERFACE= unchecked (( int )0x80004002); |
private bool _fSafeForScripting= true ; |
private bool _fSafeForInitializing= true ; |
public HelloBossmaActiveX() |
{ |
InitializeComponent(); |
} |
///<summary> |
///设置当前时间 |
///</summary> |
///<paramname="timeStr"></param> |
public void SetTime( string timeStr) |
{ |
this .label2.Text=timeStr; |
} |
public int GetInterfaceSafetyOptions( ref Guidriid, |
ref int pdwSupportedOptions, |
ref int pdwEnabledOptions) |
{ |
int Rslt=E_FAIL; |
string strGUID=riid.ToString( "B" ); |
pdwSupportedOptions=INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA; |
switch (strGUID) |
{ |
case _IID_IDispatch: |
case _IID_IDispatchEx: |
Rslt=S_OK; |
pdwEnabledOptions=0; |
if (_fSafeForScripting== true ) |
pdwEnabledOptions=INTERFACESAFE_FOR_UNTRUSTED_CALLER; |
break ; |
case _IID_IPersistStorage: |
case _IID_IPersistStream: |
case _IID_IPersistPropertyBag: |
Rslt=S_OK; |
pdwEnabledOptions=0; |
if (_fSafeForInitializing== true ) |
pdwEnabledOptions=INTERFACESAFE_FOR_UNTRUSTED_DATA; |
break ; |
default : |
Rslt=E_NOINTERFACE; |
break ; |
} |
return Rslt; |
} |
public int SetInterfaceSafetyOptions( ref Guidriid, |
int dwOptionSetMask, |
int dwEnabledOptions) |
{ |
int Rslt=E_FAIL; |
string strGUID=riid.ToString( "B" ); |
switch (strGUID) |
{ |
case _IID_IDispatch: |
case _IID_IDispatchEx: |
if (((dwEnabledOptions&dwOptionSetMask)==INTERFACESAFE_FOR_UNTRUSTED_CALLER)&& |
(_fSafeForScripting== true )) |
Rslt=S_OK; |
break ; |
case _IID_IPersistStorage: |
case _IID_IPersistStream: |
case _IID_IPersistPropertyBag: |
if (((dwEnabledOptions&dwOptionSetMask)==INTERFACESAFE_FOR_UNTRUSTED_DATA)&& |
(_fSafeForInitializing== true )) |
Rslt=S_OK; |
break ; |
default : |
Rslt=E_NOINTERFACE; |
break ; |
} |
return Rslt; |
} |
} |
} |
using System; |
using System.Collections.Generic; |
using System.Text; |
using System.Runtime.InteropServices; |
namespace HelloBossma |
{ |
[ComImport,GuidAttribute( "CB5BDC81-93C1-11CF-8F20-00805F2CD064" )] |
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] |
public interface IObjectSafety |
{ |
[PreserveSig] |
int GetInterfaceSafetyOptions( ref Guidriid,[MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions,[MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); |
[PreserveSig()] |
int SetInterfaceSafetyOptions( ref Guidriid,[MarshalAs(UnmanagedType.U4)] int dwOptionSetMask,[MarshalAs(UnmanagedType.U4)] int dwEnabledOptions); |
} |
} |
///<summary> |
///设置当前时间 |
///</summary> |
///<paramname="timeStr"></param> |
public void SetTime( string timeStr) |
{ |
this .label2.Text=timeStr; |
} |
(4)生成项目,生成这两个文件:
HelloBossma.dll
HelloBossma.tlb
是必须的,否则生成不成功。
4、HelloBossmaSetup项目
这是一个安装项目,用来生成安装程序。
(1)在项目上点右键,【添加】->【项目输出】,选择上边的HelloBossma项目
(2)在安装项目上点右键,属性
安装URL:貌似用于查找应用程序更新,具体看:
这个目录最好是实际存在的,用来存放生成的安装文件,供客户端下载安装。没有的话就随便输入一个吧。
(3)添加卸载程序
拷贝文件C:/Windows/System32/msiexec.exe文件,修改文件名为Uninstall.exe,添加到安装项目中,然后创建一个快捷方式。
在【用户的“程序”菜单下边】添加一个文件夹HelloBossma,将快捷方式拖动到这里边。
在卸载控件上点击右键,属性:
设置Arguments,就是指定要卸载的程序,后面的ProductCode可以这样获得:
选中项目,然后鼠标放到右侧的“属性”上,就可以看到ProductCode了:
(4)最后生成项目
5、制作CAB文件
(1)为了方便操作,可以将CABARC.EXE添加到环境变量中:桌面上右击“我的电脑”,“属性”,“高级”,“环境变量”,“系统变量”,找到“Path”,在后边把CABARC.EXE所在的路径添加上去,注意用分号隔开新添加的路径。
(2)准备好文件
install.inf:CAB安装配置文件
HelloBossmaSetup.msi:安装程序文件
install.inf文件的内容:
[version] |
signature="$CHICAGO$" |
AdvancedINF=2.0 |
[SetupHooks] |
hook1=hook1 |
[hook1] |
run=msiexec.exe/i"%EXTRACT_DIR%/HelloBossmaSetup.msi"/qn |
(3)执行cabarc命令
桌面左下角“开始”,“运行”,输入cmd,打开命令提示符工具,进入准备好的文件的目录,执行命令:
cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.inf
显示“Completedsuccessfully”,打开所在目录,就可以看到生成的文件了。
6、部署到网站
在网站中新建一个目录hellobossma,将生成的cab文件拷贝到里边。
新建一个网页,将控件添加到页面:
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""< a href = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</ a >"> |
< html xmlns = "<ahref=" http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</ a >"> |
< head runat = "server" > |
< title ></ title > |
< script type = "text/javascript" > |
functionSetTime(){ |
vard=newDate(); |
varvYear=d.getFullYear(); |
varvMon=d.getMonth()+1; |
varvDay=d.getDate(); |
varvHour=d.getHours(); |
varvMin=d.getMinutes(); |
varvSec=d.getSeconds(); |
document.HelloBossma.SetTime(vYear+"-"+vMon+"-"+vDay+""+vHour+":"+vMin+":"+vSec) |
} |
</ script > |
</ head > |
< body style = "font-size:12px;color:black" > |
< form id = "form1" runat = "server" > |
< div > |
< object classid = "clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB" codebase = "hellobossma/HelloBossma.CAB" width = "442" height = "87" id = "HelloBossma" name = "HelloBossma" > |
</ object > |
< br /> |
< br /> |
< input type = "button" value = "显示当前时间" onclick = "SetTime()" /> |
</ div > |
</ form > |
</ body > |
</ html > |
因为我们的ActiveX控件没有签名,所以将测试站点加到“本地Intranet”中或者“可信站点”中,并设置安全级别为“低”。
然后打开浏览器,提示安装,点击“安装”,稍等下,效果就出来了:
点击按钮,就可以通过javascript设置ActiveX控件中的时间了。
Over!
这篇文章是一个简单的例子,没有进行更广范围平台的测试,后续文章会逐渐加入。
1、方法一
(1)在VS项目中添加Com对象引用:MicrosoftHtmlObjectLibrary(mshtml.tlb)
(2)ActiveX中公开一个方法,传递window对象到ActiveX中
ActiveX中公开一个方法,接受传递进来的参数
///<summary> |
///将window对象传递进来 |
///</summary> |
///<paramname="obj">Theobj.</param> |
public void SetHtml( object obj) |
{ |
html=(mshtml.HTMLWindow2Class)obj; |
} |
window.onload= function (){ |
document.HelloBossma.SetHtml( this ); |
}; |
点击按钮的方法:
///<summary> |
///调用页面Javascript |
///</summary> |
///<paramname="sender"></param> |
///<paramname="e"></param> |
private void button1_Click( object sender,EventArgse) |
{ |
html.execScript( "CallByActiveX();" , "javascript" ); |
} |
调用javascript时还可以传递参数,这里不做演示了,自己可以试一下。
参考:
2、方法二
(1)在VS项目中添加Com对象引用:MicrosoftHtmlObjectLibrary(mshtml.tlb)
和第一种方法相同。
(2)用c#实现两个COM类,IOleClientSite和IOleContainer
using System; |
using System.Collections.Generic; |
using System.Text; |
using System.Runtime.InteropServices; |
namespace HelloBossma |
{ |
[ComImport, |
Guid( "00000118-0000-0000-C000-000000000046" ), |
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
public interface IOleClientSite |
{ |
void SaveObject(); |
void GetMoniker( uint dwAssign, uint dwWhichMoniker, object ppmk); |
void GetContainer( out IOleContainerppContainer); |
void ShowObject(); |
void OnShowWindow( bool fShow); |
void RequestNewObjectLayout(); |
} |
[ComImport, |
Guid( "0000011B-0000-0000-C000-000000000046" ), |
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] |
public interface IOleContainer |
{ |
void EnumObjects([In,MarshalAs(UnmanagedType.U4)] int grfFlags, |
[Out,MarshalAs(UnmanagedType.LPArray)] object []ppenum); |
void ParseDisplayName([In,MarshalAs(UnmanagedType.Interface)] object pbc, |
[MarshalAs(UnmanagedType.BStr)] string pszDisplayName, |
[Out,MarshalAs(UnmanagedType.LPArray)] int []pchEaten, |
[Out,MarshalAs(UnmanagedType.LPArray)] object []ppmkOut); |
void LockContainer([In,MarshalAs(UnmanagedType.I4)] int fLock); |
} |
} |
///<summary> |
///调用Javascript |
///</summary> |
///<paramname="Filenames">Thefilenames.</param> |
private void CallJavaScript( string param) |
{ |
//反射获取当前的控件的ClientSite |
TypetypeIOleObject= this .GetType().GetInterface( "IOleObject" , true ); |
object oleClientSite=typeIOleObject.InvokeMember( "GetClientSite" , |
BindingFlags.Instance|BindingFlags.InvokeMethod|BindingFlags.Public, |
null , |
this , |
null ); |
//获取Container |
IOleClientSiteoleClientSite2=oleClientSite as IOleClientSite; |
IOleContainerpObj; |
oleClientSite2.GetContainer( out pObj); |
//参数数组 |
object []args= new object [1]; |
args[0]=param; |
//获取页面的Script集合 |
IHTMLDocumentpDoc2=(IHTMLDocument)pObj; |
object script=pDoc2.Script; |
try |
{ |
//调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理 |
script.GetType().InvokeMember( "ShowNowTime" ,BindingFlags.Instance|BindingFlags.InvokeMethod|BindingFlags.Public, |
null , |
script, |
args); |
} |
catch {} |
} |
///<summary> |
///调用Javascript |
///</summary> |
///<paramname="sender"></param> |
///<paramname="e"></param> |
private void button1_Click( object sender,EventArgse) |
{ |
CallJavaScript( this .label2.Text); |
} |
function ShowNowTime(nowtime){ |
alert( "当前时间:" +nowtime); |
} |
1、更新Activex的版本:
(1)在ActiveX项目上点右键,属性,应用程序,程序集信息,最初的版本是1.0.0.0,修改为1.0.1.0
(2)修改控件,以区别1.0.0.0版本,修改V1.0.0为V1.0.1
(3)然后重新生成。
2、修改安装程序
(1)添加注册表项
在项目上点右键,视图,注册表:
在HKEY_CLASSES_ROOT下创建CLSID/{ActiveX的GUID}/InstalledVersion/,
在InstalledVersion下新建字符串值,修改字符串的值为”1,0,1,0″,
注意:删除名称中的值,自动会显示“(默认值)”,这样才能设置注册表中默认值,不要自己输入“默认值”。
(2)修改安装程序版本
修改Version为”1.0.1″,修改RemovePreviousVersions为”True”。
(3)重新生成安装程序
3、重新制作CAB安装包
cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.inf
4、修改网站
(1)将生成的CAB安装包替换原来的安装包。
(2)修改页面控件版本
< object classid = "clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB" codebase = "hellobossma/HelloBossma.CAB#version=1,0,1,0" width = "442" height = "116" id = "HelloBossma" name = "HelloBossma" > |
</ object > |
刷新页面,提示安装新的版本,直接安装就好了。
1、测试环境:Windows7+IE8
2、修改之前,直接访问页面看看,发现出错了:
出错行:document.HelloBossma.SetTime(vYear+“-”+vMon+“-”+vDay+””+vHour+“:”+vMin+“:”+vSec)
然后到控制面中没有找到安装的ActiveX程序,结合出错行,大致得出结论:ActiveX没有安装成功!
3、修改文件
install.inf:
[version] |
signature="$CHICAGO$" |
AdvancedINF=2.0 |
[SetupHooks] |
hook1=hook1 |
[Deployment] |
InstallScope=machine |
[hook1] |
run=%EXTRACT_DIR%/run.bat |
InstallScope=machine我这里只能用这个,改成user无法安装成功,原因未知。
另外在vista以后的版本只能执行cab中的文件了,所以msiexec转移到了bat中执行,添加一个bat文件。
run.bat:
setCURDIR=%cd% |
msiexec.exe/i"%CURDIR%/HelloBossmaSetup.msi"/qn |
重新制作CAB包,添加一个run.bat:
cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.infrun.bat |
输入网址,提示安装,然后出现命令运行框,然后消失。
如果安装成功,会出现控件界面。
6、一个兼容性问题
这时候会发现,浏览器左下角有javascript错误,同时点击CallJavascript发生异常。
无法将类型为“Systerm._ComObject”的COM对象强制转换为类类型“mshtml.HTMLWindow2Class”。
在XP、WindowsServer2003中都没有问题,Windows7上出现问题,可能是权限设置问题。
按照上边的提示,找到出现问题的地方:
Default.aspx:
window.onload= function (){ |
document.HelloBossma.SetHtml( this ); |
}; |
publicvoidSetHtml(objectobj) |
{ |
//问题出在这里,类型转换的问题 |
html=(mshtml.HTMLWindow2Class)obj; |
} |
public class HTMLWindow2Class |
{ |
} |
privatemshtml.IHTMLWindow2html= null ; |
publicvoidSetHtml(objectobj) |
{ |
html=objasmshtml.IHTMLWindow2; |
} |
重新编译,重新安装控件,OK了!
相关文章推荐
- C#开发ActiveX控件及制作CAB包
- C#开发ActiveX控件及制作CAB包
- Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(4)
- Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结
- 使用C#开发ActiveX控件 控件开发、制作CAB包、签名、部署
- Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结
- C#开发ActiveX控件及制作CAB包
- C#开发ActiveX控件及制作CAB包(转)
- C#开发ActiveX控件及制作CAB包(转)
- C#开发ActiveX控件及制作CAB包
- C#开发ActiveX控件及制作CAB包
- C#开发ActiveX控件及制作CAB包
- Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(1)
- Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(2)
- Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(3)
- C#开发ActiveX控件及制作CAB包
- C#开发ActiveX控件及制作CAB包
- C#开发ActiveX控件及制作CAB包
- 使用C#开发ActiveX控件 并制作Cab包
- C#开发ActiveX控件及制作CAB包