我可以将 .NET 5 COM 互操作对象与 VB6 连接吗?

Bie*_*iel 5 .net c# vb6 com com-interop

我一直在对 .NET Core COM 互操作以及如何公开它们进行一些研究。

尽管我在得出结论和理解一些概念时遇到了一些问题。我的老板告诉我,他们做了一些测试,他们认为创建可以从 VB6 中调用的 C# 代码(包括事件)的唯一方法是创建一个 .NET Framework 项目,因为它在 .NET Core 3.1 中不可用(位于他们必须使用此功能的那一刻)。

但看到前面提到的页面并做了更多研究,我确实认为 .NET Core 看起来支持这种互操作性。我不明白为什么 .NET Core 平台不能做到这一点。

如果这个问题不属于这里,我很抱歉,但是有人可以解释这个问题吗?

Sim*_*ier 12

.NET Framework、.NET Core 3 和 .NET 5/6/+ 可以向 COM 世界公开 COM 对象。这个世界包括VB6和一切能做COM的东西。

a) 创建.NET 5“NetClassLibrary”类库项目(例如使用 Visual Studio)

b) 添加NetComObject.cs包含以下代码的文件,例如:

using System;
using System.Runtime.InteropServices;

namespace NetClassLibrary
{
    [ComVisible(true)]
    [Guid("cfb2ee8b-f2ec-447c-9f0d-ac19c9a6cc26")] // TODO: change this GUID
    public class NetComObject
    {
        public string SayHello() => "Hello World from .NET " + RuntimeInformation.FrameworkDescription;
    }
}
Run Code Online (Sandbox Code Playgroud)

c) 修改 .csproj 以将EnableComHosting属性设置为true并确保针对 x86进行编译,因为 VB6 是 32 位程序(请注意,如果您使用 Excel 的 64 位 VBA,而不是 VB6,则必须针对 64 位进行编译),例如例如这个:

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

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <EnableComHosting>true</EnableComHosting>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

d) 编译,启动管理提示符并运行:

regsvr32 yourPathTo\NetClassLibrary.comhost.dll
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

e) 创建一个 VB6 项目,添加以下 VB6 代码:

Private Sub Form_Load()

    Dim obj As Object
    Set obj = CreateObject("new:{cfb2ee8b-f2ec-447c-9f0d-ac19c9a6cc26}") // TODO: use the same GUID!

    MsgBox obj.SayHello()

End Sub
Run Code Online (Sandbox Code Playgroud)

f) 运行

在此输入图像描述

注 1:您也可以使用ProgId属性,就像 COM 对象经常做的那样,您不必只坚持使用 Guid...

注 2:IDispatch在此演示中仅使用了(“延迟加载”)接口,但您IUnknown也可以使用派生接口(“早期加载”)和 TLB。不幸的是,.NET 5 不会为您创建 .TLB,您必须自己构建它或使用其他工具创建它并将其导入到 .NET 和/或 VB6 中。

  • @StayOnTarget - 这是 regasm,而不是 regtlb,但是,是的,他们改变/破坏了 COM 中从 .NET Framework 迁移到 .NET Core 中的许多内容....NET Core 不再构建任何嵌入在 .dll 或外部 .tlb 中的内容。 (2认同)
  • @Biel - 我的VB6有点生疏,但我认为你必须使用早期加载才能使用WithEvents,即:有一个tlb。,即:你仍然可以使用CreateObject,但不能使用非类型化的VB6对象,如我的例子。 (2认同)