` ActiveX 是一个开放的集成平台,为开发人员、 用户和 Web生产商提供了一个快速而简便的在 Internet 和 Intranet 创建程序集成和内容的方法。 使用 ActiveX, 可轻松方便的在 Web页中插入 多媒体效果、 交互式对象、以及复杂程序,创建用户体验相当的高质量多媒体CD-ROM。用activeX可以实现一些网页上JS无法实现的功能,比如执行串口操作,修改注册表,调用一些第三方提供的本地API等等,下面来简单介绍下如何用C#自己开发一个activeX组件。
1.新建一个类库项目:
2.更改项目属性-应用程序-程序集信息,使COM可见,生成-输出中勾选为COM互操作注册:
3.修改AssemblyInfo.cs文件,添加[assembly: AllowPartiallyTrustedCallers()]项(需要引用System.Security名称空间):
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security; // 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("XX")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("XX")]
[assembly: AssemblyProduct("XX")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(true)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("1c2ef8c7-2569-4bc3-95bf-5ce11f6054dd")] // 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AllowPartiallyTrustedCallers()]
4. 添加一个Windows用户控件,为控件类添加GUID,这个编号将用于B/S系统的客户端调用时使用:
[Guid("d887f4cb-8df1-11e6-8e82-68f728c3a6cb")]
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
}
}
5.为了提高程序的安全性,以便在客户端安装的时候在浏览器提高信任度,我们需要实现接口IObjectSafety
[ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
[PreserveSig]
int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); [PreserveSig()]
int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
}
然后在代码中实现接口:
[Guid("d887f4cb-8df1-11e6-8e82-68f728c3a6cb")]
public partial class MyControl : UserControl,IObjectSafety
{
public MyControl()
{
InitializeComponent();
}
#region 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 int GetInterfaceSafetyOptions(ref Guid riid, 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 Guid riid, 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;
} #endregion
}
6.接下来新建安装项目:
将之前的类库程序集添加到安装项目程序文件中,并在程序集属性窗口中将Register修改为:vsdraDoNotRegister
安装的时候,会在注册表中生成相应的节点,HKEY_CLASSES_ROOT\MyControl
7.最后使用的时候,将<object classid="clsid:d887f4cb-8df1-11e6-8e82-68f728c3a6cb" codebase="lib/setup.exe" id="mycontrol"></object>加入到页面上就可以调用ActiveX控件并调用其中的方法了。