虽然这是一个很长的问题,但编码和测试部分应该很容易重现。
我已经创建了两个单独Class Libraries
的C#
,我认为我遇到了由我以前的项目和试验中的现有注册表项引起的名称冲突问题。
这是我的两门课:
using System;
using System.Runtime.InteropServices;
namespace Test
{
[InterfaceType(ComInterfaceType.InterfaceIsDual),
Guid("ED5D264B-1D80-4A5D-9C14-8297D90B7037")]
public interface ITest
{
// body
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("8B261B92-8EC5-4CDC-A551-67DEB42137FF")]
[ProgId("Test.TestClass")]
public class TestClass : ITest
{
// body
}
}
和
using System;
using System.Runtime.InteropServices;
using ADODB;
namespace Test
{
[InterfaceType(ComInterfaceType.InterfaceIsDual),
Guid("ED5D264B-1D80-4A5D-9C14-8297D90B7037")]
public interface IConnection
{
// body
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("8B261B92-8EC5-4CDC-A551-67DEB42137FF")]
[ProgId("Test.Connection")]
public class Connection : IConnection
{
// body
}
}
我已经向 COM 公开了 .Net 组件,如下所示:
为了从 Excel 访问程序集,我已将ADODB 引用添加到程序集,勾选使程序集 COM 可见并注册 com interop。此外,我添加了对每个*.tlb
文件的引用(两个项目的 2 个文件),因此我可以使用早期绑定访问它们并使用 VBA Intellisense。
我在另一台机器上遵循了相同的过程,我可以使用Connection
as 类使用早期绑定。
我在想有一些旧的注册表项我没有在我的原始机器上删除,它们不允许我Connection
用作 VBE 中的类名。我已经手动扫描了我的注册表并删除了我能想到的与我的项目相关的所有内容。
我还完全删除了该项目并使用第 3 方软件扫描注册表以查找缺失dll
的 s,但这并没有帮助:/
每次我创建一个新项目时,删除所有以前注册的 GUID 并应用新的(以防万一)
使用不同的命名空间和类名 () 创建了新项目using ADODB;
我还不能像这样使用早期绑定,Test.Connection
因此我假设我有一个名称冲突问题。我怀疑是名称类Connection
导致了它,尽管我不是 100% 确定。
Test.TestClass
VBA 中的命名空间:
TestClass
我可以使用早期绑定以两种方式声明和使用该类型的实例:
Dim x as Test.TestClass
Dim x as TestClass
现在进入 VBE 对象资源管理器F2,TestClass
与其他库和使用 COM 的一般想法相比,它已正确显示。
但是,当我想使用该Test.Connection
库时,我无法按照相同的模式使用早期绑定,TestClass
因为生成的*.tlb
文件会自动更改(重命名)ProgId's
. 所以,我必须像这样绑定它
Dim x As Test.Test_Connection
Dim x As Test_Connection
并且Object Explorer
使用_
(下划线)而不是.
(点)显示名称,这很容易解释为什么会发生这种情况 - 继续阅读:)
就目前而言,我确信更改名称以避免冲突的不是 VBE 环境。它是 VS 的*.tlb
生成器。
我去了程序集文件夹并*.tlb
在Notepad++
. 我可以清楚地看到*.tlb
forTest.Connection
库已经包含带有_
s 的名称,不像Test.TestClass
which 有.
s
我试图手动编辑该*.tlb
文件,但由于它是一个混合二进制文件,它会产生一些效果,但也会导致 Excel 以一些奇怪的方式停止响应,所以我必须避免这种方法。
我想我已经很好地解释了问题是什么以及它来自哪里。现在我的问题是:
在 C# 代码中是否有任何属性可以用来告诉*.tlb
生成器不要覆盖我ProdId
的 s?
有没有其他操作*.tlb
文件的方法?
这个问题是一个问题吗?name collision
在不更改Connection
类名的情况下是否可以避免?
对于这么长的问题,我很抱歉,但我已经挖了将近一个星期了,我仍然无法解决这个问题。
ctrl注意:在使用 IntelliSense +的VBA(或 VBE 对象资源管理器)中space,似乎既没有Connection
使用也Recordset
没有使用。由于它们尚未在 VBE 环境中保留,因此我认为这与我的库本身有关。
作为此处提出此问题的参考,请参阅VBA 等效于 C# using 或 VB.NET 导入创建别名
非常感谢您的宝贵时间!