(二)通过IE安全控件认证
  如果客户机的IE未开启访问非安全标记的ActiveX控件,通过IE浏览上面的步骤开发出的ActiveX控件,发现IE会给出警告:
  此页上的 ActiveX 对象可能不安全的。 要允许它将初始化并通过脚本访问吗?
  或禁止访问。这是客户机IE的安全规则设置的,我们应该在控件开发上解决IE安全认证的问题。首先我们要了解IE是如何判断一个ActiveX控件是不安全的,参见Microsoft帮助和支持文档:
  http://support.microsoft.com/kb/216434/en-us
  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定义:
  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。