当前位置: 首页 > article >正文

.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 生成并行服务器清单。

先决条件

  • 安装 .NET Core 3.0 SDK 或更高版本。

创建库

第一步是创建库。

  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.json 和 ProjectName.comhost.dll 文件。

为 COM 注册 COM 主机

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

如果打算嵌入类型库 (TLB),建议也使用 ComRegisterFunctionAttribute 和 ComUnregisterFunctionAttribute 定义函数。 这些函数可用于注册和注销 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 属性是可选的。

例如,以下代码块将索引为 1 的 Server.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 接口协定。


http://www.kler.cn/a/507636.html

相关文章:

  • 关于vite+vue3+ts项目中env.d.ts 文件详解
  • STM32网络通讯之CubeMX实现LWIP项目设计(十五)
  • DM达梦启用及收集AWR报告
  • 《鸿蒙Next微内核:解锁人工智能决策树并行计算的加速密码》
  • 森林网络部署,工业4G路由器实现林区组网远程监控
  • 迅为RK3568开发板篇OpenHarmony配置HDF驱动控制LED-新增 topeet子系统-编写 bundle.json文件
  • (学习总结20)C++11 可变参数模版、lambda表达式、包装器与部分新内容添加
  • 5-1 创建和打包AXI Interface IP
  • 备份和容灾之区别(The Difference between Backup and Disaster Recovery)
  • PDF文件提取开源工具调研总结
  • 国产编辑器EverEdit - 复制为RTF
  • 【vue】rules校验规则简单描述
  • 人工智能之深度学习-[1]-了解深度学习
  • 动态路由vue-router
  • SpringBoot中整合RabbitMQ(测试+部署上线 最完整)
  • 【例43.3】 转二进制
  • Django学堂在线笔记-1
  • FreeRTOS 简介
  • Module 模块
  • 阿里云无影云电脑的使用场景
  • 如何在前端给视频进行去除绿幕并替换背景?-----Vue3!!
  • Redis 性能优化:多维度技术解析与实战策略
  • Java并发编程中的synchronized和volatile:用途解析与使用场景
  • opencv入门基础
  • 分多个AndroidManifest.xml来控制项目编译
  • pikachu靶机-Cross-Site Scripting(XSS)