要使用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:
• Implement the IObjectSafety interface.
• Provide the following registry keys for the control's CLSID under the Implemented Categories section:
- The following key marks the control safe for scripting:
{7DD95801-9882-11CF-9FA9-00AA006C42C4}
- 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控件发布方式有三种:
1.制作客户端安装包,分发给客户机安装;
2.制作在线安装包,客户机联机安装;
3.使用html中object的codebase指向安装包地址。
前两个比较简单,适合在局域网内实施;最后一种方式,需要在安装包上进行数字签名,以保证客户机的安全信任。受信任的签名证书应该向证书提供商(如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控件了。
分享到:
相关推荐
### 一个简单的ActiveX控件——详尽教程 在深入探讨如何开发一个简单的ActiveX控件之前,让我们先了解ActiveX控件...虽然初期可能会遇到一些挑战,但随着实践经验的积累,掌握ActiveX控件的开发将变得越来越得心应手。
在本开发指南中,我们将深入探讨ActiveX控件的创建、使用和管理。 首先,了解ActiveX控件的基础。控件是一个自包含的程序单元,可以执行特定任务,如播放音频、显示视频或处理用户输入。ActiveX控件是用COM...
在提供的压缩包中,`新建 Microsoft Word 文档.doc`可能是开发实例的详细步骤或源码的解释,而`标准MFC WinSock ActiveX控件开发实例`很可能是实际的源码文件。通过阅读文档和分析源码,你可以更深入地理解这个开发...
总之,Delphi作为一种成熟的Windows应用开发工具,不仅提供了丰富的组件库和高级编程语言,还特别针对ActiveX控件开发提供了完善的支持和优化,使得开发者能够以最小的学习成本和最少的编码量,构建出高质量的...
总的来说,MFC ActiveX控件开发涉及到组件设计、事件处理、属性和方法的定义,以及与容器的交互等多个方面,对于初学者来说,理解并掌握这些概念是构建高效、灵活的ActiveX控件的关键。通过深入学习和实践,开发者...
### Java调用ActiveX控件:深入解析与实践 #### 引言 在Web开发的早期阶段,跨平台兼容性是一大挑战。为了解决这一问题,开发者们探索了多种技术,其中一种便是通过Java调用ActiveX控件。本文将深入探讨如何在Java...
在IT行业中,C#是一种广泛使用的编程语言,尤其在Windows应用程序开发中占据重要地位。ActiveX控件是Microsoft开发的一种技术,它允许开发者...通过这些资源,开发者可以系统地学习和实践C# ActiveX控件的开发和部署。
通过学习和实践这两个例子,你可以深入理解ActiveX控件的原理和开发流程,同时增强对Windows编程的理解。对于初学者而言,这是一份非常有价值的资源,不仅可以帮助掌握基本的控件开发技巧,还能为将来深入探索COM和...
本文将深入探讨这两个主题以及如何在VC++环境中开发和使用ActiveX控件。 首先,ActiveX控件是Microsoft提出的一种组件对象模型(COM),它允许开发者创建可重用的软件组件,这些组件可以嵌入到各种应用程序中,如...
总结来说,"C# ActiveX控件开发源码"是关于使用C#语言在.NET Framework下创建和实现ActiveX控件的实践。这涉及到COM组件的概念、C#的COM互操作性以及如何在Visual Studio中进行项目设置和部署。虽然ActiveX技术在...
VS2008中的ActiveX控件开发 在VS2008中,你可以使用Visual C#或Visual Basic .NET(VB.NET)来创建ActiveX控件。首先,你需要创建一个新的项目,选择“类库”模板,然后在项目的属性中将输出类型设置为“ActiveX...
ActiveX控件是VC中一个关键的概念,它是一种基于组件的技术,允许开发者创建可重用的软件部件,这些部件可以在各种应用程序中嵌入并交互。在本篇文章中,我们将深入探讨“VC,简单的ActiveX控件”的相关知识点。 1....
本篇文章将深入探讨如何利用Visual Studio 2008的C#功能来开发ActiveX控件,以及如何制作CAB包和进行数字签名,以确保软件的安全性和可靠性。 一、Visual Studio 2008与C#开发ActiveX控件 1. 创建项目:首先,我们...
- **项目实践**:通过实际项目练习,如构建一个简单的数据库管理系统,能更好地掌握ActiveX控件的运用。 总之,Visual Basic编程与ActiveX控件的结合使得开发者能够创建功能强大且具有丰富交互性的应用程序。了解...
此外,书中的实例和案例研究将理论知识与实践相结合,让读者能够亲手操作,体验ActiveX控件的强大功能。通过这些实例,读者可以学习到如何在实际项目中有效地使用和管理ActiveX控件,提升软件开发的效率和质量。 ...
这些知识点涵盖了从基本的COM和ATL技术概念,到具体的ActiveX控件开发实践,再到与硬件设备的接口封装和交互细节。这些内容对于理解如何利用ATL技术开发ActiveX网页控件,以及如何在实际项目中部署这些控件具有重要...
在IT行业中,开发自定义控件是常见的任务之一,尤其在需要特定功能或增强应用程序界面交互性时。本文将深入探讨如何...同时,创建GIF ActiveX控件也是一个很好的实践,能够提升对图像处理和图形用户界面设计的理解。
在VC++编程环境中,ActiveX控件是一种常用的组件模型,它允许开发者创建可重用的软件组件,并在多个应用程序中嵌入使用。本教程将详细讲解如何在VC++程序内部注册ActiveX控件,以便在运行时动态地加载和使用这些控件...