我可以将 .NET 5 COM 互操作对象与 VB6 连接起来吗?
Posted
技术标签:
【中文标题】我可以将 .NET 5 COM 互操作对象与 VB6 连接起来吗?【英文标题】:Can I connect a .NET 5 COM interop object with VB6? 【发布时间】:2021-11-27 15:25:13 【问题描述】:我一直在研究 .NET Core COM 互操作和how to expose them。
虽然我在得出结论和理解一些概念时遇到了一些问题。 我的老板告诉我他们做了一些测试,他们认为创建可以从 VB6(包括事件)中调用的 C# 代码的唯一方法是创建一个 .NET Framework 项目,因为它在 .NET Core 3.1 中不可用(在他们必须使用此功能的那一刻)。
但是看到前面提到的页面并进行了更多研究,我确实认为 .NET Core 似乎支持这种互操作性。而且我不明白为什么 .NET Core 平台无法做到这一点。
如果这个问题不属于这里,我很抱歉,但是有人可以解释一下这个问题吗?
【问题讨论】:
只要付出足够的努力,一切皆有可能。你为什么想要? VB6 是一种死语言。不只是大部分都死了,它是检查口袋里的零钱死了。 无论如何,你需要更具体一些。你尝试过什么,结果如何?包括您收到的任何错误消息。 等等,你想从 VB6 调用一些 .NET 代码吗?甚至不是.NET的VB6?是的,不要那样做。我想这是可能的,但有些事情你真的不应该做。 VB6 是在 20 多年前推出的,从那时起事情就发生了变化。甚至 VB.NET 自 2002 年以来就已经存在,我认为它不会与 .NET 核心兼容 @Neil 我真的不想这样做,但我工作的公司的主要产品完全是用 VB6 编码的,他们需要我这样做......所以我就是想知道这个。他们过去已经使用了一些来自 VB6 的 .NET Framework 项目。但如果它仍然看起来超级不可能,那么我就会忘记它。谢谢你的回答! VB6 只对那些不需要支持它为生的人来说是死的(而且不一定要选择“更好”的东西)。长期以来,对于许多开发人员 (IMO) 而言,逐渐将部分 VB6 应用程序迁移到 .NET - 或在那里制作新组件 - 非常普遍。 【参考方案1】:.NET Framework、.NET Core 3+ 和 .NET 5+ 可以将 COM 对象公开给 COMworld。这个世界包括 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;
c) 修改 .csproj 以将 EnableComHosting
属性设置为 true
并确保您编译 for 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>
d) 编译,启动管理员提示并运行:
regsvr32 yourPathTo\NetClassLibrary.comhost.dll
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
f) 运行
注意 1: 你也可以使用 ProgId 属性,就像 COM 对象经常做的那样,你不必只使用 Guids...
注意 2: 我只使用了IDispatch
(“延迟加载”)接口进行此演示,但您也可以使用IUnknown
派生接口(“早期加载”)和 TLB .不幸的是,.NET 5 不会为您创建 .TLB,您必须自己构建它或使用其他工具创建它,然后将其导入 .NET 和/或 VB6。
【讨论】:
谢谢你一百万次的解释和西蒙的例子! 那么,不再像 .NET 框架中那样使用 regtlb 了吗? @StayOnTarget - 这是 regasm,而不是 regtlb,但是是的,它们改变/破坏了 COM 中从 .NET Framework 到 .NET Core 的许多东西...... .NET Core 没有构建任何嵌入.dll 或外部 .tlb 了。 @Biel - 我的 VB6 有点生锈,但我认为你必须使用早期加载才能使用 WithEvents,即:有一个 tlb。,即:你仍然可以使用 CreateObject 但你不能像我的示例那样使用无类型的 VB6 对象。 @Biel 但如果你绝对必须,请参阅docs.microsoft.com/en-us/archive/msdn-magazine/2001/march/…。以上是关于我可以将 .NET 5 COM 互操作对象与 VB6 连接起来吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 VB.NET 中使用 Word 和 Outlook 2007 的 Office 互操作