1、开发及测试环境:
(1)开发环境:
Visual Studio 2008 SP1
cabsdk(下载地址:http://support.microsoft.com/kb/310618)
(2)测试环境:
Windows Server 2003 R2 SP2
IE6
2、创建项目

我这里创建了三个项目:
(1)HelloBossma :
项目模板:Windows窗体控件库
(2)HelloBossmaSetup:
项目模板:安装项目
(3)Web:
项目模板:ASP.NET 网站
3、HelloBossma项目
这个项目用于编写具体的控件,并生成安装文件所需要的dll。
(1)添加用户控件:

(2)设计控件:

添加Panel、GroupBox、Label 控件。NowTime是一个Label控件,用于显示时间。
然后在控件对应的代码文件中编写程序:
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Windows.Forms; |
using System.Runtime.InteropServices; |
/// IObjectSafety的是用来标记可安全执行脚本的ActiveX控件 |
[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() |
/// <param name="timeStr"></param> |
public void SetTime( string timeStr) |
this .label2.Text = timeStr; |
public int GetInterfaceSafetyOptions( ref Guid riid, |
ref int pdwSupportedOptions, |
ref int pdwEnabledOptions) |
string strGUID = riid.ToString( "B" ); |
pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; |
if (_fSafeForScripting == true ) |
pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; |
case _IID_IPersistStorage: |
case _IID_IPersistStream: |
case _IID_IPersistPropertyBag: |
if (_fSafeForInitializing == true ) |
pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; |
public int SetInterfaceSafetyOptions( ref Guid riid, |
string strGUID = riid.ToString( "B" ); |
if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && |
(_fSafeForScripting == true )) |
case _IID_IPersistStorage: |
case _IID_IPersistStream: |
case _IID_IPersistPropertyBag: |
if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && |
(_fSafeForInitializing == true )) |
关于IObjectSafety的实现参考了:http://www.pinvoke.net/default.aspx/Interfaces/IObjectSafety.html
using System.Collections.Generic; |
using System.Runtime.InteropServices; |
[ComImport, GuidAttribute( "CB5BDC81-93C1-11CF-8F20-00805F2CD064" )] |
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] |
public interface IObjectSafety |
int GetInterfaceSafetyOptions( ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); |
int SetInterfaceSafetyOptions( ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions); |
这里还包含了一个可以被外部调用的方法,传进来一个字符参数,并显示出来:
/// <param name="timeStr"></param> |
public void SetTime( string timeStr) |
this .label2.Text = timeStr; |
(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=msiexec.exe /i "%EXTRACT_DIR%/HelloBossmaSetup.msi" /qn |
run:一般只需要修改这个就行了
(3)执行cabarc命令
桌面左下角“开始”,“运行”,输入cmd,打开命令提示符工具,进入准备好的文件的目录,执行命令:
cabarc n HelloBossma.cab HelloBossmaSetup.msi install.inf

显示“Completed successfully” ,打开所在目录,就可以看到生成的文件了。
6、部署到网站
在网站中新建一个目录hellobossma,将生成的cab文件拷贝到里边。
新建一个网页,将控件添加到页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//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 = "<A href=" http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</ A >"> |
< script type = "text/javascript" > |
var vYear = d.getFullYear(); |
var vMon = d.getMonth() + 1; |
var vHour = d.getHours(); |
var vMin = d.getMinutes(); |
var vSec = d.getSeconds(); |
document.HelloBossma.SetTime(vYear + "-" + vMon + "-" + vDay + " " + vHour + ":" + vMin + ":" + vSec) |
< body style = "font-size: 12px; color: black" > |
< form id = "form1" runat = "server" > |
< object classid = "clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB" codebase = "hellobossma/HelloBossma.CAB" width = "442" height = "87" id = "HelloBossma" name = "HelloBossma" > |
< input type = "button" value = "显示当前时间" onclick = "SetTime()" /> |
ActiveX控件作为一个object添加到页面中,其classid是在编写HelloBossmaActiveX类时定义好的Guid值,codebase用来指示cab安装文件的路径,还可以设置宽度、高度。另外其中文字受页面中字体样式的影响。
因为我们的ActiveX控件没有签名,所以将测试站点加到“本地Intranet”中或者“可信站点”中,并设置安全级别为“低”。

然后打开浏览器,提示安装,点击“安装”,稍等下,效果就出来了:

点击按钮,就可以通过javascript设置ActiveX控件中的时间了。
Over!
这篇文章是一个简单的例子,没有进行更广范围平台的测试,后续文章会逐渐加入。
转自:http://blog.bossma.cn/dotnet/visual-studio-2008-csharp-activex-summary-1/