As I'm working on making an out of process VB COM Server to use it in a client VB application, and bring stability to the application.
The following link of sample code from MSDN helped me in the making of VB COM server, and I successfully exposed Methods, Properties and Events from that COM Server. https://code.msdn.microsoft.com/windowsdesktop/VBExeCOMServer-a5b9f49f
I've used the COM Server in client application using following code, it worked fine for Properties and Functions calls, however, when I tried to handle an event exposed by the COM Server I get a compile time error:
Dim obj = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
obj.TestProperty = "test" // worked fine
obj.TestFunction() // worked fine
AddHandler obj.TestEvent, AddressOf TestEventHandlerFunction
// Compile Time Error!!! TestEventis not an event of 'Object'
To resolve this compile time error, I tried type casting the Object type to 'BaseControllerSimple' type using following code but with that change, I get an exception at runtime:
Dim obj As BaseControllerSimple = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
// EXCEPTION! Unable to cast COM object of type 'System.__ComObject' to class type 'MeridiaAPICOMServer.BaseControllerSimple'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Later, I tried making an interface in COM Server's code and made "BaseControllerSimple" class to implement that interface. Here is the code snippet for the interface and the class implementing it:
<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
Following is the code for the IBaseControllerSimple class
<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
After defining an interface, I tried following code:
Dim obj As IBaseControllerSimple = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
// EXCEPTION Unable to cast COM object of type 'System.__ComObject' to interface type 'IBaseControllerSimple'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{0742DA3D-1CFA-4A3D-A104-35DBECB4EA48}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
Looking forward to a solution, or any kind of feedback that would help me resolve the problem of handling events which are exposed by a VB COM Server. Thanks in advance.