在 .NET 中一步步创建 ActiveX






4.74/5 (59投票s)
本文将详细介绍如何在 .NET 中创建 ActiveX,以及如何在 HTML 页面上使用它。
引言
在我之前的工作中,我有一个项目,需要交付一个关于创建、分发和运行 ActiveX 控件(用 .NET 编写)的解决方案。本文总结了所有这些内容。文章中的所有内容都可以在网上找到,但请相信我,这并不容易;)。
Using the Code
- ActiveXSourceCode.zip - 包含 ActiveX 的 .NET 源代码
- Setup.zip - 包含创建 CAB 所需的 *.ini 文件示例
- Web.zip - 嵌入 ActiveX对象的 HTML 文件示例
那么,我们开始吧...
1) 创建 .NET ActiveX
您需要做的第一步是创建 ActiveX 控件 : )。
您可以在此处找到关于此主题的优秀介绍。
本文介绍了如何在网站上创建和公开 Windows 窗体。由于 .NET Framework 中没有此类支持,WinForms 被封装到 ActiveX 中,这正是我们需要的。总之,我们需要创建一个类,并为其添加这些属性:
[ProgId("MyClassName")]
[Guid("MyGUID")] sdf 
[ComVisible(true)] 
其中
- ProgId是将被公开为- COM对象的类的唯一名称。
- ClassInterface是包装我们 .NET 类的- COM接口的类型。
- Guid是允许我们的类用作- COM对象的唯一- GUID。要创建新的- GUID,您可以使用 Visual Studio 中的工具“工具 -> 创建- GUID”。
- ComVisible表示我们的类可以用作- COM对象。
注册 COM 对象意味着您需要在注册表中进行一些条目。您可以手动进行,也可以在 ActiveX 中编写方法,当您使用 regasm 等工具注册它时,这些方法会为您完成注册。
///<summary>
///Register the class as a control and set its CodeBase entry
///</summary>
///<param name="key">The registry key of the control</param>
[ComRegisterFunction()]
public static void RegisterClass ( string key )
{
.
.
.
}
///<summary>
///Called to unregister the control
///</summary>
///<param name="key">The registry key</param>
[ComUnregisterFunction()]
public static void UnregisterClass ( string key)
{
.
.
.
}
在实现这些方法后,您现在可以使用命令:regasm /codebase MyAssemblie.dll 来运行 RegisterClass 方法,以及使用 regasm /u MyAssemblie.dll 来运行 UnregisterClass 方法。
为了将您类中的 .NET 方法和属性公开为 COM 方法和属性,您必须在它们前面添加标记 [ComVisible(true)],例如:
[ComVisible(true)]
public void Open()
{
. 
    System.Windows.Forms.MessageBox.Show(MyParam);
.
}
[ComVisible(true)]
public string MyParam
{
    get
    {          
        return myParam;
    } 
    set
    { 
        myParam = value;
    }
} 
您必须记住,您的程序集必须使用强名称密钥进行签名,这样您才能使用更复杂的控件、程序集和功能(例如将事件传回浏览器)。要创建新的 SNK,您可以使用工具:sn.exe(可以在 .NET SDK 中找到)。
sn –k Kosmala.Michal.ActiveXReport.snk
创建强名称密钥后,将其复制到您的项目路径,并在 AssemblyInfo.cs 文件中将其路径放在
[assembly:AssemblyKeyFile("../../Kosmala.Michal.ActiveXReport.snk")] 
注册了 COM 对象类后,您现在可以在 Web 页面上使用它了。
2) 在 HTML 页面上使用 ActiveX
要在 HTML 文件中开始使用您的 ActiveX ,只需添加一个标签即可。
<OBJECT id="OurActiveX" name=”OurActiveX" classid="clsid:MyGuid" 
	VIEWASTEXT codebase="OurActiveX.cab">
其中
- id和- name是从 JavaScript 访问我们- ActiveX时使用的值。
- classid是我们- ActiveX的- GUID,我们在 C# 代码的- [Guid("MyGUID")]部分中将其放入。
- Codebase是当系统上找不到具有我们- GUID的- ActiveX时应该启动的文件路径。这是放置安装程序(封装在 CAB 中)的地方。
现在,我们暂时忽略 codebase 部分,因为我们正在计算机上进行所有操作,并且可以使用 regasm 注册 ActiveX 。
现在我们的 Web 页面知道了我们要使用哪种 ActiveX ,我们就可以开始实际使用它了。
为此,我们只需在页面上编写一些 JavaScript 代码。这段代码可能看起来像这样:
<script language="javascript">
//Passing parameters to ActiveX object
function OpenActiveX()
{
    try
    {
        document.OurActiveX.MyParam = "Hi I am here."
        document.OurActiveX.Open();
    }
    catch(Err)
    { 
        alert(Err.description);
    }
    OpenActiveX();
}
</script> 
此脚本将为 MyParam 赋值,并调用我们 C# 代码中的 Open() 方法,该方法将返回一个显示“I am here”文本的消息框。 Open 只是一个方法名,您可以任意命名。
变量赋值是双向的。您也可以使用 JavaScript 从 ActiveX 字段读取值。
请记住,在 Internet Explorer 中设置正确的安全值,以允许运行 ActiveX 。
3) 创建 .cab 组件
现在是时候创建 CAB 文件了,当浏览器在系统中找不到我们注册的 ActiveX 时,将启动该 CAB 文件。首先,您需要创建一个安装程序,该安装程序可以是 MSI,也可以是将 MSI 封装到 setup.exe 文件中。我通过使用 InstallShield 应用程序完成了此操作,因为这是我公司的标准,但您可以使用 Visual Studio 来完成(尽管我从未测试过)。重要的是,您的安装程序必须在目标计算机上注册您的 ActiveX 。这可能需要管理员权限。
有了安装程序后,您就必须创建 CAB。为此,您可以使用 cabsdk ,您可以在此处找到它。
现在,关于我们的 CAB 的重要之处在于,它不仅要附加我们的安装文件,还要附加描述 CAB 内容和应启动哪个文件的*.ini 文件。我们的 OurActiveX.ini 可能看起来像这样:
[version]
    signature="$CHICAGO 
其中
- [Add Code]部分描述了文件的哪些部分映射到哪个文件。在本例中,只有一个 setup.exe 文件,它由同名的部分映射。
- [setup.exe]部分是前一节中定义的部分。它说明了映射到的文件将在通过正确的- clsid访问时启动。在本例中,这就是我们在 C# 代码以及- <OBJECT>标签中定义的- MyGuid。
现在我们拥有了所有需要的文件,我们可以使用 cabsdk 通过以下命令创建 CAB 文件:
cabarc.exe n OurActiveX.cab OurActiveX.inf setup.exe
Voilà。我们的基本 ActiveX 及其分发属性已准备就绪。
现在,来点更复杂的 : )。
4) 从 ActiveX 调用 JavaScript 方法
有时可能需要从 ActiveX 发送一个 JavaScript 可以捕获的事件,例如,当您希望在关闭 ActiveX 时重定向网页。
为此,您需要更新 C# 代码。您需要添加一个新的 interface 和一个新的 delegate:
public delegate void ControlEventHandler(string redirectUrl);
/// <summary>
/// This interface shows events to javascript
/// </summary>
[Guid(NewGuid)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ControlEvents
{
    //Add a DispIdAttribute to any members in the source interface 
    //to specify the COM DispId.
    [DispId(0x60020000)]
    void OnClose(string redirectUrl);
} 
此代码创建了一个 interface 包装器,它将作为 COM 对象在外部可见。任何可供 COM 使用的新事件都必须标记 DispId 属性。
(创建 .NET 到 COM 对象 http://www.csharphelp.com/archives/archive281.html)
现在,我们需要继承我们的新接口到 ActiveX 控件中:
[ClassInterface(ClassInterfaceType.AutoDual), 
	ComSourceInterfaces(typeof(ControlEvents))]
由于我们实现了 ControlEvents interface,现在我们必须在类中创建 OnClose 事件,我们可以在 ActiveX 中引发该事件:
public event ControlEventHandler OnClose;
编译此代码后,我们必须使用附加参数“/tlb”注册我们的 ActiveX 控件(regasm),这将从我们的 DLL 中提取 tlb COM 库并将其注册到我们的系统中。
regasm /codebase /tlb MyAssemblie.dll
有了这样的代码,我们就可以在 JavaScript 中添加此事件的处理程序了:
<script language="javascript">
function OurActiveX::OnClose(redirectionUrl)
    { 
        window.location = hostUrl + "/" + redirectionUrl;
    }
</script>
事件仅在整个页面加载完成后附加,因此为了使用它,我们必须更改调用 JavaScript 函数的方式:OpenActiveX。现在我们有两种方法可以做到:
- 
我们可以将我们的函数附加到(例如)一个按钮,我们的 ActiveX将在我们单击它时运行:<input type=button onclick=javascript:OpenActiveX()> 
- 
如果我们希望它在页面加载后自动启动,我们必须将我们的函数附加到 body 事件“ onload”:<body onload=OpenActivex()> 
您必须记住,您的 ActiveX 程序集必须签名并使用附加参数“/tlb”进行注册。
这是一个非常简单的 ActiveX ,但它可以调用您的用户有权访问的任何 WinForms 控件或应用程序。
关注点
正如您所见,在 .NET 中创建和分发 ActiveX 非常容易,但很难在网上找到正确的答案,可能是因为现在使用 ActiveX 的人不多了。
我希望本文能尽可能地缩短您的搜索时间。
历史
- 2008 年 3 月 4 日:初始发布


