如何使用 COM 公开 .netstandard2.0 库以在 VB6 中使用?

Kir*_*eed 5 vb6 com com-interop .net-standard-2.0

我有一个 dotnet 核心库、一个框架 4.7.2 库和一个 vb6 应用程序。

我想写一个公共库供他们访问,所以选择 .netstandard2.0

我在 .netstandard2.0 库和 vb6 之间尝试了 4.7.2 框架包装库。

但是我遇到了程序集绑定问题

查看 我看到的文档

在 .NET Core 中,与 .NET Framework 相比,将 .NET 对象公开给 COM 的过程已显着简化。

但是没有提到.netstandard2.0

即使我的项目使用的是 .netstandard2.0,我还是决定尝试遵循文档

我开始阅读有关生成 COM 主机的说明,在这种情况下,应该生成输出文件 ProjectName.dll、ProjectName.deps.json、ProjectName.runtimeconfig.json 和 ProjectName.comhost.dll。

但是 ProjectName.comhost.dll 和 ProjectName.runtimeconfig.json 不会创建。

我在这个dotnet 标准问题中看到 Microsoft 计划在“预览 4”中提供工具支持

我正在运行 VS 16.4.5

[更新]

我决定尝试制作一个 .net 核心包装库并为 com 启用它。

我能够通过 nuget 包将我的 .netstandard 添加到包装库(我使用 azure devops 构建了 .netstandard 库)

当我构建我的包装库时,在 bin\Debug\netcoreapp3.1 文件夹中创建了 .dll、.deps.json、.pdb、.runtimeconfig.dev.json 和 .runtimeconfig.json 文件。

然而,没有任何 .netstandard 库文件出现在 bin\debug 文件夹中。

我将 .netstandard 库和 .netcore 包装器库复制到同一个文件夹并运行

regsvr32 MyCoreComWrapper.comhost.dll  
Run Code Online (Sandbox Code Playgroud)

但是没有创建 .tlb 文件,我需要能够从 VB6 使用

我在文档中注意到以下内容

与 .NET Framework 不同,.NET Core 不支持从 .NET Core 程序集生成 COM 类型库 (TLB)。该指南是为 COM 接口的本机声明手动编写 IDL 文件或 C/C++ 头文件。

在 github 上找到了一些信息但我会喜欢制作 .tlb 的分步指南

我考虑过使用后期绑定,但不确定如何将它与 com 库一起使用。

[更新]

我在GitHub 上放了一个示例项目,其中包括一些 VB6 文件。使用 VB6 引用框架库引用的 .tlb。

当我尝试运行时,我得到

Could not load file or assembly 'Microsoft.EntityFrameworkCore, Version=3.1.2.0, 
Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.
Run Code Online (Sandbox Code Playgroud)

所以我将框架测试项目中的所有文件复制到我的 vb6 文件夹中,重新构建并运行。

然后我得到了错误

Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.0.0, 
Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.
Run Code Online (Sandbox Code Playgroud)

我看到文件 Microsoft.Extensions.DependencyInjection.dll 与文件版本 3.100.220.6706 一起存在

Sim*_*ier 4

该问题是由于从 VB6(IDE 或编译的 .exe 文件)运行时程序集绑定解析失败造成的。

以下是解决该问题的步骤:

  • 以编译VB项目为例,假设编译后的文件为Project1.exe.
  • 将所有 .NET 程序集(包括 x86 和 x64 目录,以及语言目录(如果本地化版本很重要))复制到已编译的 VB6 文件旁边
  • 现在运行Project1.exe,你会得到这样的错误:

在此输入图像描述

该错误显然是文件旁边的程序集版本Project1.exe与引用程序集的版本之间不匹配(不是您自己创建的引用,而是嵌入在这些程序集中的引用...)。当您启动 .NET 程序时,您看不到这一点,因为解析是一个非常复杂的过程,依赖于很多参数(并且对于 .NET Core、Framework、Standard、nugets 等,它并没有变得更好)。

要进一步检查是否存在不匹配错误,您还可以使用SDK 中的Fuslogvw.exe(程序集绑定日志查看器)工具。

现在我们知道这是程序集版本不匹配问题,您可以做的是创建一个名为Project1.exe.configaside的文件Project1.exe并向其添加程序集绑定重定向

配置它的最简单方法是将所有可能的版本重定向到包含程序的目录中存在的版本,因此在您的情况下(截至今天,所有这些都可以发展......),它会是这样的,可能对于您直接或间接引用的每个程序集:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      ...
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" />
        <!-- 3.1.2.0 is the version of the assembly you ship -->
        <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="3.1.2.0" />
      </dependentAssembly>
      ...
    </assemblyBinding>
  </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

不幸的是,有许多附属程序集,并且使用正确的信息创建所有重定向有点乏味,因此我创建了一个工具,该工具可以创建一个.config文件,其中为给定目录中的所有 .NET 程序集自动配置重定向:https:// /github.com/smourier/BindingRedirectGenerator

如果您希望它也适用于 VB6 IDE,则必须在VB6.exe.config旁边的文件中使用相同的过程VB6.exe