按照 Microsoft 的 ComWrappers 源生成 文章,我使用 GenerateComInterfaceAttribute 在 Visual Studio 2022 中创建了一个简单的 .NET 8 类库项目。我的类基于另一个 Stack Overflow 问题中描述的类似类,其中使用了 .NET 5。
这是默认的代码
Class1.cs
:
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace ComHostTest
{
[GeneratedComClass]
[Guid("63C60D62-317F-4BAB-BB20-0AB41F34A345")]
public partial class Class1
{
public string SayHello() => "Hello World from .NET " + RuntimeInformation.FrameworkDescription;
}
}
这是我的项目文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x86</PlatformTarget>
<EnableComHosting>true</EnableComHosting>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
</Project>
我的构建配置和 PlatformTarget 设置为 x86。该项目正确构建并生成
ComHostTest.comhost.dll
:
使用提升的命令提示符,我成功注册了 comhost.dll:
然后,使用 VB6 IDE 的“引用”窗口或 OLEViewer,我没有看到 ComHostTest 程序集作为可用的 COM 类型库:
知道为什么吗?
我已经读过这个非常相似的问题,其中该人也使用 .NET 8,但不使用 GenerationComInterfaceAttribute。
我根据 Simon Mourier 的评论调整了我的代码:
using System.Runtime.InteropServices;
namespace ComHostTest
{
[ComVisible(true)]
[Guid("72433A8C-941E-4876-8CC2-15F6F4235F32")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IComHostTest
{
public string SayHello();
}
[ComVisible(true)]
[Guid("63C60D62-317F-4BAB-BB20-0AB41F34A345")]
[ClassInterface(ClassInterfaceType.None)]
public class ComHostTest : IComHostTest
{
public string SayHello() => "Hello World from .NET " + RuntimeInformation.FrameworkDescription;
}
}
项目文件未被触及,因为它已经包含了
<EnableComHosting>true</EnableComHosting>
。
我从 GitHub 下载了 dscom32 版本,然后从 Visual Studio 中的 Developer PowerShell 窗口执行了以下命令:
dscom32 tlbexport "D:\.NET Projects\Development\COM host\ComHostTest\bin\x86\Debug\net8.0\ComHostTest.dll"
这生成了一个 ComHostTest TLB 文件,我将其包含在我的 .csproj 文件中:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x86</PlatformTarget>
<EnableComHosting>true</EnableComHosting>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<ComHostTypeLibrary Include="ComHostTest.tlb" Id="1" />
</ItemGroup>
</Project>
仍然没有运气在 VB6 IDE 中看到它,但我一定很接近了。
根据 Simon Mourier 的评论和他对类似问题的回答,我设法让该库显示在 VB6 的参考列表中。
首先,简单的部分。这是接口和类的代码:
using System.Runtime.InteropServices;
namespace ComHostTest
{
[ComVisible(true)]
[Guid("72433A8C-941E-4876-8CC2-15F6F4235F32")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IComHostTest
{
public string SayHello();
}
[ComVisible(true)]
[Guid("63C60D62-317F-4BAB-BB20-0AB41F34A345")]
[ClassInterface(ClassInterfaceType.None)]
public class ComHostTest : IComHostTest
{
public string SayHello() => "Hello World! from .NET " + RuntimeInformation.FrameworkDescription;
}
}
.csproj 文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x86</PlatformTarget>
<EnableComHosting>true</EnableComHosting>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<ComHostTypeLibrary Include="ComHostTest.tlb" Id="1" />
</ItemGroup>
</Project>
您应该能够构建这个项目并获得
ComHostTest.comhost.dll
。使用 regsvr32 注册此 DLL。
下一步是从 GitHub 获取
dscom32.exe
。您可以从dSPACE-group/dscom Releases获取编译版本。该工具将从您的 DLL 生成 TLB 文件:
dscom32 tlbexport "D:\.NET Projects\Development\COM host\ComHostTest\bin\x86\Debug\net8.0\ComHostTest.dll"
然后,使用相同的工具来注册TLB:
dscom32 tlbregister "D:\.NET Projects\Development\COM host\ComHostTest\bin\x86\Debug\net8.0\ComHostTest.tlb"
这应该返回:
类型库注册成功
最后,在 VB6 中,打开“参考文献”窗口并找到您的库:
您现在应该能够在 IntelliSense 中查看并创建类的实例:
所有功劳都归功于西蒙·穆里尔。