.NET Core 2.1 - 如何创建COM对象并生成*.tlb文件

9

我想在 .net Core 中构建 COM 对象,然后通过 RegAsm 进行注册。

我的 .csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>netcoreapp2.1;net4.7.2</TargetFrameworks>
    <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
    <Platforms>x64</Platforms>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
</Project>

我的 program.cs:

using System;
using System.Runtime.InteropServices;

namespace ComExample
{
    [Guid("7ce1e40f-760a-4d81-b70b-61108ed15cb4")]
    [ComVisible(true)]
    public interface IComExampleClass
    {
        IComModelClass ExampleMethod(string param1, string param2);

    }

    [Guid("a8436b3f-3657-4a01-a133-fd333a84cb58")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    public class ComExampleClass : IComExampleClass
    {
        public IComModelClass ExampleMethod(string param1, string param2)
        {
            return new ComModelClass()
            {
                Result = $"{param1} + {param2}"
            };
        }
    }

[Guid("9f5aeede-ec3e-443d-8ba0-9a9f2a6b9e53")]
[ComVisible(true)]
public interface IComModelClass
{
    string Result { get; set; }
}

[Guid("526c6cb5-264d-4629-a894-fff02aeb9ec1")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class ComModelClass : IComModelClass
{
    public string Result { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var test = new ComExampleClass();
        Console.WriteLine(test.ExampleMethod("A", "B").Result);
        Console.ReadKey();
    }
}

在使用.netcore2.1目标框架发布项目后,我无法使用c:\Windows\Microsoft.NET\Framework64\v4.0.30319中的RegAsm注册COM。

将项目发布到net4.7.2后,我可以通过RegAsm注册程序集,然后在CPP项目中使用它。

我也无法使用TblExp.exe从.net core项目生成tlb文件。

这看起来很奇怪。我可以注册.Net Standard程序集。如果我使用上述源代码创建.Net Standard库并使用以下csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

</Project>

然后 RegAsm 能够良好地工作。

RegAsm.exe /tlb:C:\[...]\DotnetStandardCom\bin\Debug\netstandard2.0\DotnetStandardCom.tlb C:\[...]\DotnetStandardCom\bin\Debug\netstandard2.0\DotnetStandardCom.dll

Microsoft .NET Framework Assembly Registration Utility version 4.7.3062.0
for Microsoft .NET Framework version 4.7.3062.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Types registered successfully
Assembly exported to 'C:\[...]\DotnetStandardCom\bin\Debug\netstandard2.0\DotnetStandardCom.tlb', and the type library was registered successfully

但是为什么我无法注册 .Net Core 程序集?

2
你为什么要使用.NET Core来注册COM对象?我认为这根本不可能,并且它只能在Windows上运行,所以你最好使用完整的.NET Framework版本,不是吗? - Isma
2
.NETCore团队并不急于提供工具支持。除了它永远无法移植到*nix之外,没有任何意义。您可以在任何可以使用此代码的计算机上始终使用桌面版框架。在CoreCLR中替换mscoree.dll管道不容易,因此请不要期待它。 - Hans Passant
我在dotnet core的github上创建了两个问题 https://github.com/dotnet/corefx/issues/31359 和 https://github.com/dotnet/coreclr/issues/19120。 - Wojtpl2
3
一个概念。将所有可重用的代码放入一个 .Net Standard 程序集中,然后创建一个薄的完整框架包装器,围绕你的 .Net Standard 程序集公开 Com 接口。 - Sql Surfer
但是如果没有完整的.Net安装或版本低于4.6.1怎么办?我的项目使用了.Net标准2,可以在.Net框架4.6.1中使用。https://learn.microsoft.com/pl-pl/dotnet/standard/net-standard .Net Core支持Windows 7 SP1和Windows 8.1。这些系统默认没有安装.Net Framework 4.6。 https://blogs.msdn.microsoft.com/astebner/2007/03/14/mailbag-what-version-of-the-net-framework-is-included-in-what-version-of-the-os/ - Wojtpl2
2个回答

16
由于 .NETCore 版本 3 的工作,这现在是可能的。正如我在评论中提到的,在早期的 .NETCore 版本中托管是缺失的,并且没有 mscoree.dll 的替代品。版本 3 提供了 comhost.dll。此外,它们现在还可以支持 C++/CLI 代码,ijwhost.dll 是替代品。 您可以像传统的 COM 服务器一样使用 Regsvr32.dll 注册组件。 您需要知道的所有内容都在一个月前加入的 MSDN 页面 中提供。请注意,.NETCore 3 目前仍处于预览质量阶段。而且这只适用于 Windows,没有迁移到 Linux 和 macOS 的路径,因为 COM 太过依赖只在 Windows 上可用的服务。

3
作为 COM 的替代方案,您可以在本机进程中托管 .NET Core 运行时以调用托管代码。
托管 .NET Core 运行时是一个高级场景,在大多数情况下,.NET Core 开发人员不需要担心托管,因为 .NET Core 构建过程提供了默认主机来运行 .NET Core 应用程序。然而,在某些专业情况下,显式托管 .NET Core 运行时可能会有用,无论是作为在本机进程中调用托管代码的手段,还是为了更好地控制运行时的工作方式。
链接:
- 托管 .NET Core - 在您自己的进程中托管 .NET Core Clr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接