VB6程序无法看到VB.Net COM DLL的属性

5

我的客户在全球范围内安装了一个VB6程序。现在需要通过REST API访问外部系统。我创建了一个VB.Net类库,针对.NET Framework 4进行了定位。(这是目前已经在各处安装的最新版本)。该DLL公开了约十几个公共函数和子例程以及约40个属性。我使用以下PowerShell代码测试了该DLL:

[System.Reflection.Assembly]::LoadFile( "$directorypath\Debug\MyExample.dll")
$quotaInstance = new-object MyExample.ComClass1

所有的方法和属性都可以从PS脚本中访问。然而,当我将DLL加载到VB6 IDE中时,对象浏览器只显示方法,而不是属性。如果我无法解决这个问题,我将不得不将它们重新编码为一堆函数和子程序。我讨厌那个想法。
问题如何在.NET DLL中使属性对COM可见(方法可以工作)看起来很相似,但我没有(明确地,请参见下文)使用接口,而且我不确定这个问题是否曾经得到回答。
有人知道发生了什么,并且(更重要的是)如何修复它吗?谢谢!
更新:人们要求看到我的代码,所以这里是一个简化的示例。我猜测由于InterfaceId,Visual Studio Community 2017正在为我创建某种接口。
<ComClass(Example.ClassId, Example.InterfaceId, Example.EventsId)>
Public Class Example

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "099bfc91-1f82-4a26-b1e0-d9645bb1714d"
    Public Const InterfaceId As String = "13e9763d-455c-4d89-8323-cc4e7ae7648e"
    Public Const EventsId As String = "773feeba-e635-4411-b175-30b345afa841"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    ' *** Auto-implemented properties
    ' When you declare an auto-implemented property, Visual Basic automatically
    ' creates a hidden Private field called the backing field to contain the
    ' Property value. The backing field name is the auto-implemented Property
    ' name preceded by an underscore (_).

    Public Property Foo As String
    Public Property Bar As Integer

    Public Function InitiateSession(ExampleServer As String) As Boolean
        ' Creates a new API_session.
        ' Returns True if the connection was successful, otherwise False
        ' ...
    End Function

    Public Sub CloseSession()
        ' Releases the current API_session.
        ' ...
    End Sub
End Class

1
“如何修复它?”- 修复什么?您没有展示类是如何指定的。话虽如此,对于VB来说他们做得非常简单。请参阅:ComClassAttribute。这将告诉编译器生成所需接口并正确地装饰它们以获得所需属性。 - TnTinMn
@TnTinMn 我已经完成了所有的工作,正如我所说,PowerShell 可以看到属性,但旧版本的 VB 却不能。 - samwyse
1
由于某些原因,编译器实现的 ComClass 接口生成对于自动实现属性无法正常工作。您需要使用 Get 和 Set 的长格式。同时指出像 Powershell 这样的 .Net 应用程序可以看到一个 .Net 类是毫无意义的。 - TnTinMn
@TnTinMn 谢谢!请把它作为答案回复,我会将其标记为已接受的答案。 - samwyse
3个回答

4

由于某些未知原因,VB编译器为标记了ComClassAttribute的类提供的自动生成接口会忽略自动实现的属性。您需要明确地编写长格式属性。

因此,您需要使用长格式而不是自动实现形式:

Public Property Foo As String

您需要:

Private _Foo As String
Public Property Foo As String
    Get
        Return _Foo
    End Get
    Set(value As String)
        _Foo = value
    End Set
End Property

为了使 Foo 能够包含在 COM 接口中。

0

我不是VB的粉丝,但希望下面的例子能有所帮助

Public Class Class1
    Implements IClass1

    Property Property_1 As Int32 Implements IClass1.Property_1
        Get
            Return Property_1
        End Get
        Set(value As Int32)
            Property_1 = value
        End Set
    End Property
End Class

Public Interface IClass1
    Property Property_1 As Int32
End Interface

感谢提供示例代码。我之前没有编写公共接口(因为我不知道我需要它),但现在我再次查看了所有内容,我希望/期望<ComClass(...)>可以创建我所需的一切。 - samwyse

0
如果您的属性是像List<T>这样的通用类型,则无法导出到COM。
如果是这种情况,您应该从.NET编译器看到一些构建警告。
(问题没有显示示例,因此我不知道是否在此处适用。)

感谢您的建议。我已经在上面添加了我的项目示例代码。在内部,我正在使用通用类型,但是所有属性都是字符串、整数和单精度浮点数。花了一些时间,但在发布代码之前我已经消除了所有构建警告。 - samwyse

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