如何使用 COM 公开 .netstandard2.0 库以在 VB6 中使用? [英] How do I expose a .netstandard2.0 library with COM for use in VB6?

查看:11
本文介绍了如何使用 COM 公开 .netstandard2.0 库以在 VB6 中使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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 库)

当我构建包装库时,.dll、.deps.json、.pdb、.runtimeconfig.dev.json 和 .runtimeconfig.json 文件会在 binDebug etcoreapp3.1 文件夹中创建.

但是 bindebug 文件夹中没有任何 .netstandard 库文件.

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

regsvr32 MyCoreComWrapper.comhost.dll

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

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

<块引用>

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

我在 github 上找到了一些信息

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

要进一步检查它是否是不匹配错误,您还可以使用 Fuslogvw.exe (Assembly Binding Log Viewer) SDK 工具.

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

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

<配置><运行时><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">...<依赖程序集><assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60"/><!-- 3.1.2.0 是您发布的程序集的版本 --><bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="3.1.2.0"/></dependentAssembly>...</assemblyBinding></运行时></配置>

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

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

I have a dotnet core library, a framework 4.7.2 library and a vb6 application.

I want to write a common library for them all to access and so choose .netstandard2.0

I tried a the 4.7.2 framework wrapper library between .netstandard2.0 library and vb6.

However I ran into assembly binding problems

Looking at the docs I see

In .NET Core, the process for exposing your .NET objects to COM has been significantly streamlined in comparison to .NET Framework.

However no mention .netstandard2.0

I decided to try following the docs anyway even though my project is using .netstandard2.0

I got up to the instructions on Generating the COM Host in which case the output files ProjectName.dll, ProjectName.deps.json, ProjectName.runtimeconfig.json and ProjectName.comhost.dll should build.

However the ProjectName.comhost.dll and ProjectName.runtimeconfig.json do not create.

I see in this dotnet standard issue that Microsoft plans on having tooling support in "Preview 4"

I am running VS 16.4.5

[Update]

I decided to try making a .net core wrapper library and enabling it for com.

I was able to add my .netstandard to the wrapper library via a nuget package (I build the .netstandard library using azure devops)

When I build my wrapper library the .dll, .deps.json, .pdb, .runtimeconfig.dev.json and .runtimeconfig.json files are created in a binDebug etcoreapp3.1 folder.

However none of the .netstandard library files appear in the bindebug folder.

I copied the .netstandard library and the .netcore wrapper libraries to the same folder and ran

regsvr32 MyCoreComWrapper.comhost.dll  

However no .tlb file is created which I need to be able to use from VB6

I note the following in the docs

Unlike in .NET Framework, there is no support in .NET Core for generating a COM Type Library (TLB) from a .NET Core assembly. The guidance is to either manually write an IDL file or a C/C++ header for the native declarations of the COM interfaces.

I found some information on github but would love a step by step guide to making the .tlb

I thought about using latebinding instead but am unsure of how to use it with a com library.

[Update]

I put a sample project on GitHub including some VB6 files. With VB6 referencing the .tlb referenced with the framework library.

When I try to run that I get

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.

So I copied all the files from my framework test project to my vb6 folder, rebuilt and ran.

Then I got the error

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.

I see the file Microsoft.Extensions.DependencyInjection.dll is present with File version 3.100.220.6706

解决方案

The issue is due to assembly binding resolution that fails when ran from VB6 (IDE or compiled .exe file).

Here are the steps to solve it:

  • Compile the VB project, for example, let's assume the compiled file is Project1.exe.
  • Copy all .NET assemblies (including x86 and x64 directories, and languages directory if localized version is important) aside the compiled VB6 file
  • Now run Project1.exe, you will get an error like this:

The error is clearly a mismatch between the version of your assemblies aside the Project1.exe file and the version of referenced assemblies (not references you've created yourself but reference embedded in these assemblies... ). You don't see that when you start a .NET program because resolution is a very complex process that depends on a lot of parameters (and it's not getting any better with .NET Core, Framework, Standard, nugets, etc.).

To futher check it's a mismatch error, you can also use the Fuslogvw.exe (Assembly Binding Log Viewer) tool from the SDK.

Now we know it's an assembly version mismatch issue, what you can do is create a file named Project1.exe.config aside Project1.exe and add assembly binding redirects to it.

The easiest way to configure it is to redirect all possible versions to the ones present in the directory that contains your program, so in your case (and as of today, as all these can evolve...), it would be something like this, possibly for every assembly you reference directly or indirectly:

<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>

Unfortunately, there are many satellite assemblies, and it's a bit tedious to create all redirects with correct information, so I've created a tool that creates a .config file with the redirects configured automatically for all .NET assemblies in a given directory: https://github.com/smourier/BindingRedirectGenerator.

If you want it to work for the VB6 IDE too, you'll have to use the same procedure in a VB6.exe.config file aside VB6.exe.

这篇关于如何使用 COM 公开 .netstandard2.0 库以在 VB6 中使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆