要使用C#实现一个ActiveX控件
要使用C#实现一个ActiveX控件,需要解决三个问题:
1.使.NET组件能够被COM调用
2.在客户机上注册后,ActiveX控件能通过IE的安全认证
3.未在客户机上注册时,安装包能通过IE的签名认证
本程序的开发环境是.NET Framework 3.5,工具是Visual Studio .NET 2008,在安装.NET Framework 3.5的客户机上通过测试。
下面是实现步骤:
(一)创建可从COM访问的程序集
首先实现一个对COM可见的程序集,创建类库工程,AssemblyInfo.cs应包含:
using System.Runtime.InteropServices; //使此程序集中的类型对COM组件可见
[assembly: ComVisible(true)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("94882155-3B7C-48e3-B357-234D56D8F15E")]
加入以下代码到AssemblyInfo.cs确保程序集的可访问性:
using System.Security; [assembly: AllowPartiallyTrustedCallers()]
注意上面的Guid,如果程序集内部的类未标注Guid,COM注册的Guid是会新生成的,此处的Guid没有作用。
创建用户控件(自定义类待测)IdentityKey.cs,加入:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices; namespace KeyActiveX
{
[Guid("94882155-3B7C-48e3-B357-234D56D8F15E")]
public partial class IdentityKey : UserControl
{
}
}
这里的Guid和AssemblyInfo.cs一样,它会在COM注册中成为CLSID并被html以clsid调用。
类库工程属性中,选择生成,勾选COM注册,在html文件中加入
<object id="controlbyid" classid="clsid:{94882155-3B7C-48e3-B357-234D56D8F15E}" ></object>
在IE中启用不安全控件,查看html页面,应能访问到控件,现在一个在发布时对COM注册的程序集开发完成了。
使用OLE/COM Object Viewer(安装VC自带)可以在.NET Categories中查看组件和CLSID。
(二)通过IE安全控件认证
如果客户机的IE未开启访问非安全标记的ActiveX控件,通过IE浏览上面的步骤开发出的ActiveX控件,发现IE会给出警告:
此页上的 ActiveX 对象可能不安全的。 要允许它将初始化并通过脚本访问吗?
或禁止访问。这是客户机IE的安全规则设置的,我们应该在控件开发上解决IE安全认证的问题。首先我们要了解IE是如何判断一个ActiveX控件是不安全的,参见Microsoft帮助和支持文档:
How Internet Explorer Determines If ActiveX Controls Are Safe
There are two ways to mark a control as safe for scripting and initialization:
1.Implement the IObjectSafety interface.
2.Provide the following registry keys for the control's CLSID under the Implemented Categories section:
a.The following key marks the control safe for scripting:
{7DD95801-9882-11CF-9FA9-00AA006C42C4}
b.The following key marks the control safe for initialization from persistent data:
{7DD95802-9882-11CF-9FA9-00AA006C42C4}
Microsoft recommends that you implement IObjectSafety to mark a control as safe or unsafe. This prevents other users from repackaging your control and marking it as safe when it is not.
我决定实现IObjectSafety接口来向IE表明ActiveX控件的安全标识,以保证控件再次打包时安全标识不会被被改写。
IObjectSafety是一个COM下的接口,对于C++程序来说,只需要实现它就行了,而.NET之下没有这个接口,在这种情况下,我们的ActiveX控件就是一个不带类型库的COM组件,必须使用C#代码重新定义COM接口。
这里需要了解一点COM的接口知识。接口是COM的核心,它区分了在客户和对象之间使用的契约和实现。COM的接口有三种类型:定制接口÷分派接口和双重接口。.NET Framework使用ComInterfaceType对它进行了重定义:
namespace System.Runtime.InteropServices
{
// 摘要:
// Identifies how to expose an interface to COM.
[Serializable]
[ComVisible(true)]
public enum ComInterfaceType
{
// 摘要:
// Indicates the interface is exposed to COM as a dual interface, which enables
// both early and late binding. System.Runtime.InteropServices.ComInterfaceType.InterfaceIsDual
// is the default value.
InterfaceIsDual = 0,
//
// 摘要:
// Indicates an interface is exposed to COM as an IUnknown -derived interface,
// which enables only early binding.
InterfaceIsIUnknown = 1,
//
// 摘要:
// Indicates an interface is exposed to COM as a dispinterface, which enables
// late binding only.
InterfaceIsIDispatch = 2,
}
}
关于三个接口的具体描述,可以参考《C#高级编程第三版》28.1.3 接口。
在MSDN上查找,可以知道IObjectSafety继承自IUnknown,是一个定制接口;通过上一章节,可以发现向COM注册时,需要提供一个Guid作为CLSID来标识程序集中的C#类,事实上在COM中,接口和类型库都是带有Guid作为唯一标识的,分别为IID和typelib id。
这样,通过在C#编写的接口标上需要的COM接口IID,就可以在注册是向COM表明接口身份了。在Microsoft帮助上查找IObjectSafety定义:
[
uuid(C67830E0-D11D-11cf-BD80-00AA00575603),
helpstring("VB IObjectSafety Interface"),
version(1.0)
]
library IObjectSafetyTLB
{
importlib("stdole2.tlb");
[
uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064),
helpstring("IObjectSafety Interface"),
odl
]
interface IObjectSafety:IUnknown {
[helpstring("GetInterfaceSafetyOptions")]
HRESULT GetInterfaceSafetyOptions(
[in] long riid,
[in] long *pdwSupportedOptions,
[in] long *pdwEnabledOptions); [helpstring("SetInterfaceSafetyOptions")]
HRESULT SetInterfaceSafetyOptions(
[in] long riid,
[in] long dwOptionsSetMask,
[in] long dwEnabledOptions);
}
}
其中的uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064)就是需要的接口IID。
使用C#编写IObjectSafety:
using System;
using System.Runtime.InteropServices; namespace KeyActiveX
{
[ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
[PreserveSig]
void GetInterfacceSafyOptions(
int riid,
out int pdwSupportedOptions,
out int pdwEnabledOptions); [PreserveSig]
void SetInterfaceSafetyOptions(
int riid,
int dwOptionsSetMask,
int dwEnabledOptions);
}
}
InterfaceType中一定要使用ComInterfaceType.InterfaceIsIUnknown,因为IObjectSafety继承自IUnkown。
接下来是KeyActiveX的接口实现:
namespace KeyActiveX
{
[Guid("94882155-3B7C-48e3-B357-234D56D8F15E")]
public partial class IdentityKey : UserControl, IObjectSafety
{
#region IObjectSafety 成员 public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
{
pdwSupportedOptions = 1;
pdwEnabledOptions = 2;
} public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
{
throw new NotImplementedException();
} #endregion
}
}
通过返回一个已定值来告诉IE控件是安全的。具体参见
如何在 VisualBasic 控件实现 IObjectSafety
(三)签名发布
C#开发的ActiveX控件发布方式有三种:
- 制作客户端安装包,分发给客户机安装;
- 制作在线安装包,客户机联机安装;
- 使用html中object的codebase指向安装包地址。
前两个比较简单,适合在局域网内实施,生成安装包时需要装Register属性设置为vsdrpCOM;最后一种方式,需要在安装包上进行数字签名,以保证客户机的安全信任。受信任的签名证书应该向证书提供商(如Versign)购买,然后使用签名工具对安装包进行签名。
下面利用Visual Studio 2008自带的测试证书创建工具MakeCert和签名工具SignTool进行测试,首先创建一个带有公司信息的测试证书,在Visual Studio命令提示符后输入:
makecert -sk ABC -n "CN=ABC Corporation" f:\abccorptest.cer
在F盘上创建了测试证书。然后输入
signtool signwizard
在Signing Options页面上,选择Custom,定义证书文件的位置,再下一步选择一个加密算法(MD5或SHA1),指定应用程序的名称和描述URL,确认。
此时ActiveX控件安装包有了一个被标记为未信任的测试证书,需要将IE设置为启用未信任安装程序,在html中引用
<object id="controlbyid" classid="clsid:{94882155-3B7C-48e3-B357-234D56D8F15E}" codebase="setup.exe" ></object>
客户机安装之后就可以使用ActiveX控件了。
要使用C#实现一个ActiveX控件的更多相关文章
- 开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件
ActiveX开发的教程有很多,我也从中受益匪浅,例如以下这几篇: 基本教程:http://www.cnblogs.com/guenli/articles/1629915.html 注意事项:http ...
- 使用C#开发ActiveX控件(新)
前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...
- [转]C#开发ActiveX控件,.NET开发OCX控件案例
引自:百度 http://hi.baidu.com/yanzuoguang/blog/item/fe11974edf52873aaec3ab42.html 讲下什么是ActiveX控件,到底有什么 ...
- ActiveX控件的基本操作方法以及如何在VS2010下使用控件
在此,小编就介绍下ActiveX控件的基本操作方法以及如何在VS2010下使用控件,我们以一个程序为例, (1) 打开VS2010编译器(右键以管理员身份运行,因为ActiveX需要注册), ...
- 在VS2010中ActiveX控件注册方法,使用regsvr32命令
上一篇小编展示了如何设置VS2010自带的ActiveX控件的容器测试程序,现在为大家演示一下如何注册ActiveX控件. 首先简单了解一下ActiveX控件的知识,ActiveX控件:简单来说,就是 ...
- 使用C#开发ActiveX控件(新) 转 http://www.cnblogs.com/yilin/p/csharp-activex.html
前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...
- ActiveX控件
什么是ActiveX控件:一个进程内服务器,支持多种的COM接口.(可以理解为,一个COM接口是一个纯抽象基类,你实现了它,并且它支持自注册,就是一个ActiveX控件了)可以把ActiveX控件看做 ...
- [转] 使用C#开发ActiveX控件
双魂人生 原文 使用C#开发ActiveX控件 ActiveX 是一个开放的集成平台,为开发人员.用户和 Web生产商提供了一个快速而简便的在 Internet 和 Intranet 创建程序集成和内 ...
- 常用的Activex 控件
1. Flash Player ActiveX Control 6.0.47.0 与FLASH 6.0配套的浏览器端动画播放插件 download.pchome.n ...
随机推荐
- U3D模拟仿真实现
最近在做一个模拟仿真系统,数据源是一个实时数据库,场景中包含一些监测点.监测点给信号的方式是有物体到了监测点给上料信号,物体离开了监测点给下料信号:注意,如果有多个物体到达或离开监测点,那给信号的时间 ...
- linux CentOS 上安装chrome
1.wget http://chrome.richardlloyd.org.uk/install_chrome.sh (用wget下载shell文件)2.chmod u+x install_chr ...
- mini_httpd在RedHat 5下安装
1.安装mini_httpdcd /usr/src/redhat/SOURCES wget http://www.acme.com/software/mini_httpd/mini_httpd-1.1 ...
- logstash收集nginx日志
(1)安装nginx 1.安装nginx yum install epel-release -y yum install nginx -y 2.修改日志文件格式为json #vim /etc/ngin ...
- js的循环
1.for(){} 这种方法可能每个人都用过,不多说. 2.ES5的forEach myArray.forEach(function (value) { console.log(value); }); ...
- 《Android虚拟机》----Android系统的结构
No1: 操作系统层包括各种驱动程序:显示.Flash内存.照相机.音频.WiFi.键盘.蓝牙.Binder IPC.能源管理. 各种库和Android运行环境大多是用C和C++实现的. Androi ...
- Python之路【第五篇】: 函数、闭包、装饰器、迭代器、生成器
目录 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之可迭代对象 函数之迭代器 函数之生成器 面向过程的程序设计思想 一.函数进阶之函数对象 1. 函数对象 秉承着 ...
- 使用log4j输出日志
今天在倒腾log4j,其实蛮简单的. 一.首先是下载log4j的jar包. 二.将下载的jar包添加到web工程的WEB-INF/lib包下 三.在src/config包下新建log4j.proper ...
- 单纯用JS做的分页插件
最近公司需要用到分页插件,由于市面上大多都是jQuery的分页插件,而且项目中有自己的工具类,所以说我在工具类中又添加了不依赖jQuery的分页插件,而且分页插件来说对DOM的操作也不是很多,就是用J ...
- java _循环练习和数组练习
练习 1.输出所有的水仙花数,所谓水仙花数是指一个数3位数,其每位数字立方和等于其本身,如153 = 1*1*1 + 3*3*3 + 5*5*5(很经典的题目) 分析: 通过观察发现,本题目要实现打印 ...