日期:2014-05-17  浏览次数:20393 次

ActiveX控件开发
http://www.cnblogs.com/RCFans/archive/2009/06/26/1333982.html 
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.