如何将公开COM的.NET项目添加到VB6(或VBA)引用对话框中?

11
我创建了一个.NET程序集,根据Phil Wilson的杰出文章 构建和部署.NET COM程序集 ,该程序集暴露给COM。
一切都正常工作,即.NET程序集已正确注册为COM,编译的COM代码可以调用它而没有任何问题。
唯一奇怪的是,当使用VB 6.0或VBA开发针对公开的COM .NET程序集时,需要浏览到相关.tlb文件的确切文件位置,然后一切都可以正常工作。也就是说,类库不会直接显示在“引用”对话框中,因此您必须浏览到文件位置。
再次强调,COM互操作方面的功能确实百分之百可行;但是,我认为必须有某些设置,使得VB 6.0和VBA中的库可以直接在“引用”对话框中显示。
有人知道这个设置是什么吗?还是说只要注册了,这应该自动发生?
非常感谢任何建议...
迈克 编辑/更新 为了回答jpoh的问题,我想说明一下我正在使用.msi安装程序包,而不是显式地使用RegAsm,并且程序集已经被正确注册。可以在HKCR\CLSID{myGUID}\InprocServer32中看到,“CodeBase”键正确保存了程序集的完整路径。编译后的COM组件可以很好地执行该dll,但只有在使用VB 6.0或VBA进行开发时,它们才不会出现在“引用”对话框中。因此,我需要“浏览”到正确的文件位置,之后就可以完美地工作了。
更新#2
进一步研究后发现,尽管类GUID已经被正确注册,但我的.tlb文件没有被注册。我不知道为什么。注册.tlb文件应该在HKCR\Interface{myInterfaceGUID}上放置一些接口的注册表条目,但这并没有发生。奇怪的是,这种缺乏注册似乎不影响dll的功能,除了在VB6和VBA的“引用”对话框中无法找到它。
设置项目中我的.tlb文件的属性似乎是正确的:'PackageAs'属性设置为'vsdpaDefault','Register'属性设置为'vsdrfCOM'。我困惑于为什么这不能成功地安装在目标计算机上。
更新#3
好吧,事实证明设置项目并没有成功构建...尽管它报告“构建成功”。
实际上,有一个构建警告(令人惊讶的是,这是一个警告而不是错误),报告说它无法为文件名为“DotNetLibrary3.tlb”的文件创建注册信息。由于这是一个警告而不是错误,编译状态显示“构建成功”,而错误列表未打开。
追踪下来,似乎在Vista是您的开发机器时尝试创建安装程序项目时,可能会出现此问题,如此处所述: 在VS2008设置项目中出现COM类型库注册问题 这里描述了一种有点手动的修复方法: 反馈:无法为名为“文件名”的文件创建注册信息 我还没有尝试过修复方法,但明天我会尝试并报告是否解决了问题。
第四次更新
那做得不太好……看起来当在Vista上运行时,如该文章所建议的运行RegCap.exe是无效的。由于RegCap实际上是由设置项目自身在创建.msi时内部运行的,因此这并不奇怪。简而言之,安装程序项目几乎肯定失败,因为它调用的RegCap命令失败了……因此直接调用RegCap是没有帮助的。
底线是,这只是在Vista上创建安装包时遇到的一个错误。或者,可能是Visual Studio 2008和Vista的组合,我不确定。在Windows XP上运行的Visual Studio 2005上尝试完全相同的方法来创建设置项目没有任何问题。
很可能有修复程序可以在Vista和/或Visual Studio 2008上正确运行它,但我找不到它们。对我来说更有效的方法是使用Windows XP上的Visual Studio 2005构建以生成COM注册要求,然后将它们导入我的Visual Studio 2008设置项目。可以通过针对dll使用/regfile开关使用regasm和对.tlb文件使用RegCap(在W'XP上运行!)将它们导出为.REG文件。由于我的COM接口不会改变,因此我只需要做一次。
希望在运行于Vista上的Visual Studio 2008中解决这个问题,但如果不能,希望这篇文章对发现自己处于同样情况的其他人有所帮助...
另请参阅: 如何在VB.NET中编写的Excel COM服务器中获取已安装并注册的自动化服务器列表? - Mike

澄清:TLB未注册不会阻止编译的DLL使用您的COM DLL,如果GUID没有更改。 TLB的唯一目的是在设计时向IDE提供类型信息,并在构建时向编译器提供类型信息,但是一旦针对您的COM DLL构建了DLL,则从技术上讲不再需要TLB(GUID在构建DLL时已“硬连线”)。因此,使用您的COM程序集的现有DLL将在没有TLB的情况下工作。 - Mike Spross
进一步澄清,TLB 文件最初是需要的,以便注册 COM 组件,但在类和接口 ID 注册后,就不再需要了。当您实例化 COM 类时,COM 不会查看 TLB 文件或注册表中的 TypeLib 条目。只有在对象实例化时,CLSID 和 IID 才有意义。 - Mike Spross
谢谢Mike,那是非常清晰的解释,很有道理。谢谢! - Mike Rosenblum
你是否曾经在Vista+VS 2008上得到过令人满意的解决方案?我正在使用VB.NET制作Excel插件,并且它必须作为COM服务器公开,我已经尝试了您在此处列出的每个死胡同。 - hughdbrown
嗨,休,我先看到了你的帖子,然后才注意到你在这里的评论。所以我在那里回复了你:https://dev59.com/t3I_5IYBdhLWcg3wJfgM#1506932 - Mike Rosenblum
5个回答

2
你的regasm命令中是否包含/codebase标志?

实际上,我正在使用一个 .msi 安装包,而不是显式地使用 RegAsm。程序集被正确注册了——在 HKCR\CLSID{myGUID}\InprocServer32 中,“CodeBase”键正确地保存了程序集的完整路径。 - Mike Rosenblum
编译后的COM组件可以很好地找到并执行,只有在使用VB 6.0或VBA开发时,我需要“浏览”到正确的文件位置。还有其他设置、文件位置或注册表值需要吗?或者我的安装出了什么问题? - Mike Rosenblum
参考对话框中的条目来自于 HKCR\TypeLib 注册表键,而不是 HKCR\CLSID。如果您的程序集在“引用”对话框中没有显示出来,但编译的 DLL 仍然可以使用您的 COM 程序集,则表示类和接口已正确注册到您的程序集中,但类型库本身未被注册。这似乎是 VS2008 在 Vista 中的一个错误,正如您链接到的论坛主题中所提到的那样。从 MSI 显式运行 regasm 应该可以解决这个问题。 - Mike Spross
啊,明白了,这解释了谜团,Mike。这很有道理,因为我得到的行为正是这样:引用dll的编译代码运行良好,但要针对dll进行开发需要浏览到dll位置。你从MSI中显式运行Regasm的想法是一个好主意。相反,我在W'XP机器上使用Regasm和Regcap开发所需的.REG文件,并利用这些文件从MSI中获取,但无论如何,在Vista上开发时都必须绕过MSI的默认行为。一个奇怪的错误。感谢你的想法,Mike,这很有帮助。 :-) - Mike Rosenblum

2

我知道这是很久以前的事情了,但我找不到任何合理的答案。我曾经遇到过类似的问题,解决方法是使用安装它的相同用户运行Visual Studio。如果我以不同的用户身份运行它,除了COM注册以外的所有功能都无法正常工作。


0

Typelib注册表条目将在注册表中丢失。 您需要使用Microsoft.NET\framework\文件夹中与您构建程序集的.NET版本相对应的regtlibv12 [path]MyTypeLib.tlb。 这样做后,附加的注册表条目将存在,并且VBA引用可以找到它。 或者在Windows 10中,我使用位于windows文件夹中的regtlib.exe [path]MyTypeLib.tlb 然后,您必须重新收集安装程序集,以便现在具有typelib条目。我个人使用wix安装程序,并使用'heat'来实现此目的。Regasm /regfile无法完成此操作。 对.dll和.tlb都使用heat以获取classid和typelib注册表条目。


0

如果在Vista下运行VS2008,但没有提升权限,它不会发出警告。 提升权限是我们(Vista用户)学习始终使用该工具的方式,但是出于某种原因,对于这个问题,以另一种方式更好。

N.B.:当我提升权限时,我的启动了某种SQL Server工具的安装程序,最终我可以跳过它,但是当没有提升权限运行时,它会尝试再次安装并因权限问题而失败。 但似乎不影响实际的构建结果。


Atario,谢谢你的建议。下次我会试一试。(而且肯定会有下次!)可能要等好几周才能再试一次,但是当我再试的时候,我会回来告诉你结果的。非常感谢你的建议。 - Mike Rosenblum

0
您可以在 .net 项目中使用生成 TLB 和 ComVisibleAttribute 的功能来创建一个扩展名为 tlb 的文件,以及 Ija dll,现在您可以将此文件添加到您的 com 级别项目中并享受此功能。 但需要注意的是,需要安装与主项目相关的 .NET 版本。 输入图像描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接