进程外COM服务器和事件处理

时间:2016-04-04 11:35:08

标签: vb.net com out-of-process

因为我正在努力使进程外的VB COM服务器在客户端VB应用程序中使用它,并为应用程序带来稳定性。

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

我使用以下代码在客户端应用程序中使用了COM服务器,它适用于属性和函数调用,但是,当我尝试处理COM服务器公开的事件时,我得到编译时错误:< / p>

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

// 编译时错误!!! TestEvent不是&#39;对象&#39;

的事件

要解决此编译时错误,我尝试将对象类型转换为&#39; BaseControllerSimple&#39;使用以下代码键入但使用该更改,我在运行时得到一个异常:

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

// EXCEPTION!无法转换类型为&#39; System .__ ComObject&#39;的COM对象。类类型&#39; MeridiaAPICOMServer.BaseControllerSimple&#39;。表示COM组件的类型实例不能转换为不代表COM组件的类型;但是只要底层的COM组件支持对接口的IID的QueryInterface调用,它们就可以转换为接口。

后来,我尝试在COM Server的代码中创建一个接口,并制作了#34; BaseControllerSimple&#34;用于实现该接口的类。以下是接口和实现它的类的代码片段:

<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")

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

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

0 个答案:

没有答案