在暴露给COM的类库中引发事件

Ant*_*ony 1 vb.net vb6 com interop

我正在尝试为服务编写一个包装器,它将由现有的VB6项目使用.我有大部分基本框架工作,除了一个重要方面:我可以在VB6项目中引用包装器和子/函数调用等按预期工作,但事件不会.这些事件在VB6应用程序中可见,但它们从未触发过.

VB.NET代码:

Public Event Action_Response(ByVal Status as String)
Public Function TestEvent()
    RaiseEvent Action_Response("Test Done")
    Return "Done"
End Function
Run Code Online (Sandbox Code Playgroud)

VB6代码:

Dim WithEvents my_Wrapper as Wrapper_Class
Private Sub cmdTest_Click()
    Set my_Wrapper = New Wrapper_Class
    Debug.Print my_Wrapper.TestEvent() 
End Sub

Private Sub my_Wrapper_Action_Response(ByVal Status As String)
    Debug.Print Status
    Set my_Wrapper = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)

因此,cmdTest按钮代码按预期打印"完成",但不会触发Action_Response事件.我还需要做些什么来让事件发生吗?

Dar*_*inH 7

在评论中写的太多了,所以我会把它作为答案....

首先,确定要向COM公开的.net类.我会选一个名为CORE的课程.

创建一个描述CORE对象将要生成的事件(即生成)的接口.

<ComVisible(True)> _
<Guid("some guid here...use guidgen, I'll call it GUID1")> _
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface ICoreEvents
    <System.Runtime.InteropServices.DispId(1)> _
    Sub FileLoaded(ByVal Message As String)
End Interface
Run Code Online (Sandbox Code Playgroud)

接下来,为COM公开的属性和类的方法创建一个接口.

<ComVisible(True)> _
<Guid("another GUID, I'll call it guid2")> _
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _
Public Interface ICore
    ReadOnly Property Property1() As Boolean
    ReadOnly Property AnotherProperty() As ISettings
    ReadOnly Property Name() As String
    ReadOnly Property Phone() As String
End Interface
Run Code Online (Sandbox Code Playgroud)

现在,创建您的实际.net类

<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
<ComDefaultInterface(GetType(ICore))> _
<ComSourceInterfaces(GetType(ICoreEvents))> _
<Guid("a third GUID, I'll call it GUID3")> _
Public Class Core
    Implements ICore

    <System.Runtime.InteropServices.ComVisible(False)> _
    Public Delegate Sub OnFileLoaded(ByVal Message As String)
    Public Event FileLoaded As OnFileLoaded
End Class
Run Code Online (Sandbox Code Playgroud)

现在,当您需要引发FileLoaded事件时,只需从您的类中提取RAISEEVENT FILELOADED(消息)..NET会将事件转发给COM,因为您已连接COMSourceInterfaces属性.

该属性是其中大部分内容的简写,但遗憾的是并不能完全控制您需要执行某些操作(例如,保留com接口上的版本兼容性).