0

因为我正在制作一个进程外的 VB COM 服务器,以便在客户端 VB 应用程序中使用它,并为应用程序带来稳定性。

以下来自 MSDN 的示例代码链接帮助我制作了 VB COM 服务器,并且我成功地从该 COM 服务器公开了方法、属性和事件。https://code.msdn.microsoft.com/windowsdesktop/VBExeCOMServer-a5b9f49f

我使用以下代码在客户端应用程序中使用了 COM 服务器,它在属性和函数调用中运行良好,但是,当我尝试处理由 COM 服务器公开的事件时,出现编译时错误:

Dim obj = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
obj.TestProperty = "test" // worked fine
obj.TestFunction() // worked fine
AddHandler obj.TestEvent, AddressOf TestEventHandlerFunction

//编译错误!!!TestEvent 不是“对象”的事件

为了解决此编译时错误,我尝试使用以下代码将 Object 类型强制转换为“BaseControllerSimple”类型,但随着该更改,我在运行时遇到异常:

Dim obj As BaseControllerSimple = CreateObject("MeridiaAPICOMServer.BaseControllerSimple") 

//例外!无法将类型为“System.__ComObject”的 COM 对象转换为类类型“MeridiaAPICOMServer.BaseControllerSimple”。表示 COM 组件的类型的实例不能转换为不表示 COM 组件的类型;但是,只要底层 COM 组件支持对接口的 IID 的 QueryInterface 调用,它们就可以转换为接口。

后来,我尝试在 COM Server 的代码中制作一个接口,并制作了“BaseControllerSimple”类来实现该接口。这是接口和实现它的类的代码片段:

<ComImport(), ComVisible(True), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), _
Guid("0742da3d-1cfa-4a3d-a104-35dbecb4ea48")> _
Public Interface IBaseControllerSimple

<DispId(1)> Event TestEvent(ByVal portName As String, ByVal baseID As Long)
<DispId(2)> Sub TestFunction()
<DispId(3)> Property TestProperty() As String

End Interface

以下是 IBaseControllerSimple 类的代码

<ComClass(BaseControllerSimple.ClassId, BaseControllerSimple.InterfaceId, BaseControllerSimple.EventsId), ComVisible(True)> _
Public Class BaseControllerSimple
    Inherits ReferenceCountedObject
    Implements IBaseControllerSimple
Public Const ClassId As String _
= "9b5a0579-4f03-4a48-8d29-79dbbdbd32a9"
Public Const InterfaceId As String _
= "0742da3d-1cfa-4a3d-a104-35dbecb4ea48"
Public Const EventsId As String _
= "496a6535-4d44-4ee2-be02-ed69938e799b"

' These routines perform the additional COM registration needed by 
' the service.

<ComRegisterFunction(), EditorBrowsable(EditorBrowsableState.Never)> _
Public Shared Sub Register(ByVal t As Type)
    Try
        COMHelper.RegasmRegisterLocalServer(t)
    Catch ex As Exception
        Console.WriteLine(ex.Message) ' Log the error
        Throw ex ' Re-throw the exception
    End Try
End Sub

<EditorBrowsable(EditorBrowsableState.Never), ComUnregisterFunction()> _
Public Shared Sub Unregister(ByVal t As Type)
    Try
        COMHelper.RegasmUnregisterLocalServer(t)
    Catch ex As Exception
        Console.WriteLine(ex.Message) ' Log the error
        Throw ex ' Re-throw the exception
    End Try
End Sub

 Public Sub New()
    MyBase.New()
End Sub

Public Event TestEvent(ByVal portName As String, ByVal baseID As Long) _
    Implements IBaseControllerSimple.TestEvent

// TestFunction and TestProperty are also implemented and defined here...
End Class

定义接口后,我尝试了以下代码:

Dim obj As IBaseControllerSimple = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")

//异常无法将“System.__ComObject”类型的 COM 对象转换为接口类型“IBaseControllerSimple”。此操作失败,因为 IID 为“{0742DA3D-1CFA-4A3D-A104-35DBECB4EA48}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE)) .

期待解决方案或任何类型的反馈,以帮助我解决处理由 VB COM 服务器公开的事件的问题。提前致谢。

4

0 回答 0