.NET Core封装Activex Dll,向COM公开.NET Core组件

向 COM 公开 .NET Core 组件

  • 项目
  • 2024/10/22
  • 11 个参与者

向 COM 公开 .NET Core 组件 - .NET | Microsoft Learn

本文内容

  1. 先决条件
  2. 创建库
  3. 生成 COM 主机
  4. 为 COM 注册 COM 主机

显示另外 5 个

本文分步介绍如何将类从 .NET Core(或 .NET 5+)公开到 COM。 本教程介绍了如何:

  • 从 .NET Core 向 COM 公开类。
  • 生成 COM 服务器作为构建 .NET Core 库的一部分。
  • 自动为无注册表 COM 生成并行服务器清单。

先决条件

创建库

第一步是创建库。

  1. 创建新文件夹,并在该文件夹中运行以下命令:

    .NET CLI复制

    复制代码
    dotnet new classlib
  2. 打开 Class1.cs

  3. using System.Runtime.InteropServices; 添加到文件顶部。

  4. 创建名为 IServer 的接口。 例如:

    C#复制

    复制代码
    using System;
    using System.Runtime.InteropServices;
    
    [ComVisible(true)]
    [Guid(ContractGuids.ServerInterface)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IServer
    {
        /// <summary>
        /// Compute the value of the constant Pi.
        /// </summary>
        double ComputePi();
    }
  5. [Guid("<IID>")] 属性添加到接口,包含要实现的 COM 接口的接口 GUID。 例如 [Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")]。 请注意,此 GUID 必须唯一,因为它是 COM 的此接口的唯一标识符。 在 Visual Studio 中,可通过转到"工具">"创建 GUID",打开"创建 GUID"工具来生成 GUID。

  6. [InterfaceType] 属性添加到接口,并指定接口应实现的基本 COM 接口。

  7. 创建用于实现 IServer 的名为 Server 的类。

  8. [Guid("<CLSID>")] 属性添加到类,包含要实现的 COM 类的类标识符 GUID。 例如 [Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")]。 与接口 GUID 一样,此 GUID 必须唯一,因为它是 COM 的此接口的唯一标识符。

  9. [ComVisible(true)] 属性添加到接口和类。

重要

与 .NET Framework 不同,.NET Core 要求指定想要通过 COM 激活的任何类的 CLSID。

生成 COM 主机

  1. 打开 .csproj 项目文件并在 <PropertyGroup></PropertyGroup> 标记中添加 <EnableComHosting>true</EnableComHosting>
  2. 生成项目。

生成的输出将具有 ProjectName.dllProjectName.deps.jsonProjectName.runtimeconfig.jsonProjectName.comhost.dll 文件。

为 COM 注册 COM 主机

打开提升的命令提示符,然后运行 regsvr32 ProjectName.comhost.dll。 这将使用 COM 注册所有公开的 .NET 对象。

如果打算嵌入类型库 (TLB),建议也使用 ComRegisterFunctionAttributeComUnregisterFunctionAttribute 定义函数。 这些函数可用于注册和注销 COM 服务器的 TLB。 有关完整的示例,请参阅 OutOfProcCOM 示例。

启用 RegFree COM

  1. 打开 .csproj 项目文件并在 <PropertyGroup></PropertyGroup> 标记中添加 <EnableRegFreeCom>true</EnableRegFreeCom>
  2. 生成项目。

生成的输出现在还将具有 ProjectName.X.manifest 文件。 此文件是用于无注册表的 COM 的并行清单。

在 COM 主机中嵌入类型库

与 .NET Framework 不同,.NET Core 或 .NET 5+ 中不支持从 .NET 程序集生成 COM 类型库 (TLB)。 本指南旨在说明如何为 COM 接口的本机声明手动编写 IDL 文件或 C/C++ 标头。 如果决定编写 IDL 文件,可使用 Visual C++ SDK 的 MIDL 编译器对其进行编译来生成 TLB。

在 .NET 6 及更高版本中,.NET SDK 支持在项目生成过程中将已编译的 TLB 嵌入 COM 主机。

若要在应用程序中嵌入类型库,请执行以下步骤:

  1. 打开 .csproj 项目文件并在 <ItemGroup></ItemGroup> 标记中添加 <ComHostTypeLibrary Include="path/to/typelib.tlb" Id="<id>" />
  2. <id> 替换为正整数值。 在指定要嵌入 COM 主机的 TLB 中,该值必须是唯一的。
    • 如果你只将一个 Id 添加到项目中,则 ComHostTypeLibrary 属性是可选的。

例如,以下代码块将索引为 1Server.tlb 类型库添加到 COM 主机:

XML复制

复制代码
<ItemGroup>
    <ComHostTypeLibrary Include="Server.tlb" Id="1" />
</ItemGroup>

在默认 AssemblyLoadContext 中加载

在激活期间,包含 COM 组件的程序集将基于程序集路径加载到单独的 AssemblyLoadContext 中。 如果有一个程序集提供多个 COM 服务器,则重用 AssemblyLoadContext,以便该程序集中的所有服务器都位于同一加载上下文中。 如果有多个程序集提供 COM 服务器,则将为每个程序集创建一个新的 AssemblyLoadContext,并且每个服务器位于其程序集所对应的加载上下文中。

在 .NET 8 及更高版本中,程序集可以指定应在默认 AssemblyLoadContext 中加载它。 若要在默认上下文中启用加载,请将以下 RuntimeHostConfigurationOption 项添加到项目:

XML复制

复制代码
<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Runtime.InteropServices.COM.LoadComponentInDefaultContext" Value="true" />
</ItemGroup>

示例

GitHub 上的 dotnet/samples 存储库中有一个正常运行的 COM 服务器示例

附加说明

重要

在 .NET Framework 中,32 位和 64 位客户端可以使用"任何 CPU"程序集。 默认情况下,在 .NET Core、.NET 5 和更高版本中,"任何 CPU"程序集附带了 64 位的 *.comhost.dll 。 因此,它们只能由 64 位客户端使用。 这是默认的,因为这是 SDK 表示的内容。 此行为与发布"自包含"功能的方式相同:默认情况下,它使用 SDK 提供的内容。 NETCoreSdkRuntimeIdentifier MSBuild 属性确定 *.comhost.dll 的位数。 正如预期的那样,托管部分的位数实际上是不可知的,而随附的本机资产默认为目标 SDK。

不支持 COM 组件的自包含部署。 仅支持 COM 组件的依赖框架的部署

不支持通过 EnableComHosting 属性C++/CLI 项目公开 COM 组件。

此外,将 .NET Framework 和 .NET Core 同时加载到同一进程具有诊断限制。 主要限制是调试托管组件,因为不能同时调试 .NET Framework 和 .NET Core。 此外,这两个运行时实例不共享托管程序集。 这意味着无法在两个运行时之间共享实际的 .NET 类型,所有交互必须仅限于公开的 COM 接口协定。

相关推荐
啦啦啦_99992 分钟前
Redis-0-业务逻辑
数据库·redis·缓存
晚霞的不甘4 分钟前
Flutter for OpenHarmony 构建简洁高效的待办事项应用 实战解析
flutter·ui·前端框架·交互·鸿蒙
百思可瑞教育15 分钟前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
自不量力的A同学33 分钟前
Redisson 4.2.0 发布,官方推荐的 Redis 客户端
数据库·redis·缓存
Exquisite.36 分钟前
Mysql
数据库·mysql
全栈前端老曹1 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
R1nG8631 小时前
CANN资源泄漏检测工具源码深度解读 实战设备内存泄漏排查
数据库·算法·cann
阿钱真强道1 小时前
12 JetLinks MQTT直连设备事件上报实战(继电器场景)
linux·服务器·网络·数据库·网络协议
逍遥德2 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
笨蛋不要掉眼泪2 小时前
Redis哨兵机制全解析:原理、配置与实战故障转移演示
java·数据库·redis·缓存·bootstrap