65.9K
CodeProject 正在变化。 阅读更多。
Home

在 .NET 中一步步创建 ActiveX

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (59投票s)

2008年3月4日

CPOL

7分钟阅读

viewsIcon

1193843

downloadIcon

60305

本文将详细介绍如何在 .NET 中创建 ActiveX,以及如何在 HTML 页面上使用它。

引言

在我之前的工作中,我有一个项目,需要交付一个关于创建、分发和运行 ActiveX 控件(用 .NET 编写)的解决方案。本文总结了所有这些内容。文章中的所有内容都可以在网上找到,但请相信我,这并不容易;)。

Using the Code

那么,我们开始吧...

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$"
    AdvancedINF=2.0 
[Add.Code]
    setup.exe=setup.exe
[setup.exe]
    file-win32-x86=thiscab
    clsid={MyGuid}

其中

  • [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。现在我们有两种方法可以做到:

  1. 我们可以将我们的函数附加到(例如)一个按钮,我们的 ActiveX 将在我们单击它时运行:

    <input type=button onclick=javascript:OpenActiveX()>
  2. 如果我们希望它在页面加载后自动启动,我们必须将我们的函数附加到 body 事件“onload”:

    <body onload=OpenActivex()>

您必须记住,您的 ActiveX 程序集必须签名并使用附加参数“/tlb”进行注册。

这是一个非常简单的 ActiveX ,但它可以调用您的用户有权访问的任何 WinForms 控件或应用程序。

关注点

正如您所见,在 .NET 中创建和分发 ActiveX 非常容易,但很难在网上找到正确的答案,可能是因为现在使用 ActiveX 的人不多了。

我希望本文能尽可能地缩短您的搜索时间。

历史

  • 2008 年 3 月 4 日:初始发布
© . All rights reserved.