all groups > dotnet interop > october 2004 >
You're in the

dotnet interop

group:

Firing COM Events from C# Class



Firing COM Events from C# Class Tyler
10/31/2004 1:35:39 AM
dotnet interop: I would like to know what is required in order to create a C# class that can
fire events to a COM object. I have seen many posts of the reverse
(catching COM object events in C#), but not many of the case where the C#
class is firing the events.

As an example, consider a MyProject Active X DLL project with a MyClass
class defined as follows:

Option Explicit

Public Event MyEvent(ByVal MyData As String)

Public Function Initialize(ByVal fvbStart As Boolean) As String
End Function

Then, I create a C# class (reference the VB interface DLL, turn COMVisible
on, and implement the interface) as follows:

using System;
using System.Runtime.InteropServices;

namespace CSharpTest
{
[Guid("b05432d9-5a53-4bff-b1dd-68d5fe414f16")]
public class InterfaceTestClass : MyProject.MyClass
{
public InterfaceTestClass()
{
return;
}

public string Initialize(bool fvbStart)
{
return "OK";
}

public event MyProject.__MyClass_MyEventEventHandler MyEvent;
}
}

Finally, I create a VB EXE (simple form with 1 button) as follows to use my
C# component:
Option Explicit
Dim MyTest1 As MyProject.MyClass
Dim WithEvents MyTest2 As MyProject.MyClass

Private Sub Command1_Click()
Set MyTest1 = CreateObject("CSharpTest.InterfaceTestClass")
Set MyTest2 = CreateObject("CSharpTest.InterfaceTestClass")
End Sub

Every time, I get a "Runtime Error 459 - Object or class does not support
the set of events". What must I do so that my C# object will expose that it
does events? I have seen reference to the ComSourceInterfaces attribute,
but I'm not sure how to use that in this case as I've only seen it
demonstrated where the event interface is defined in C#.

I have attached the samples I created to demonstrate this problem. Any help
would be greatly appreciated!

Thanks, Tyler


begin 666 Sample.zip
M4$L#! H``````"X,7S$````````````````+`) `0U-H87)P5&5S="]31'L`
M``$````(``#QZWQC9&!I$&%@8#!@@ `?(&9D!3-918'$_=1TAGV9AAY6]2JF
MZUAPRS$R,3 P,6QA8 ?),DLP_&>49P")@=0J``D%$)M9!"+."!$7`E,J$#$\
M=C)P@US(( #5Q\P`M6,E@Q"*'8H@-I,$`T@+-G$F+.(`550-``<WAX1!.(>$
M02*%A$%02P,$% `"``@`EKM>,;HQ^.G.`P``P0D``!H`>@!#4VAA<G!497-T
M+T%S<V5M8FQY26YF;RYC<U-$90"\``````@`_1C>*F-D8&D086!@,&" `!\@
M9F0%,UE%@<3]U'2&?9F&'E;U*J;K6'#+,3(Q,# Q%#"P@*4E&/XSRC. Q$!J
M%8"$`I@M`A%GA(@+@2D5B!@>.T'FK6000C%/$<@&`%54#0`'ZUN$02MYA$$2
M=X1!C59M;]LV$/[<`OT/!P-%G2)3UWW,A@&;LPS!T""HLP[#L@\4=;*82*3
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
MD^NL2-M_<Z&9M?W%ZO/"#%; ()0G9U9MOJX6EZ>[E=X*\JKSTQVK$'R'P]=
M:=KB]?<XO.]-'MW%&'N,<KH2VGU_OA@PR?.%LN?%IJ[5M6;#,!8I>\TGY-@-
MZ"0CM1X2Z"1+BRC.9JZ2<3F;?XQ'IYG\(R"7MECJ=#F#'W'HTQ>NR0T@X*>9
M?@SIV9SP0=@%W/%@6SDFO+9_NFSQ]&9_4)43/?US]K-TO+5_G\>NQQRCGY0I
M9NT2' Y3G)Z#&WFI4MV\K9.A* (VIS39.059XB ZL\O&VUV#7.8X2[=:W6O=
MKM;;>J?:U!VKVNT9C6JC90^ZS5:G4^\WCG6<<2;'Z6=VG%G+/%_,VN?FWU3W
MC8/#25XL2.Q#5C04/N\<)OO:VI?H,%Q1S<NK1C=>[AM>A_JY=T:EL>6)W3<1
M>2^(I K')L]1ZB87C97L@U7WZQ#$^3^FM%D[]+U9>Q\DLY9^?)*/9BW[$]77
M+W\!4$L#!!0``@`(`"L,7S$02XMZM@$``!H(```A`'H`0U-H87)P5&5S="]#
M4VAA<G!497-T+F-S<')O:BYU<V5R4T1E`+P`````" #]&-XJ8V1@:1!A8& P
M8( `'R!F9 4S646!Q/W4=(9]F88>5O4JINM8<,LQ,C$P,#$4,+" I248_C/*
M,X#$0&H5@(0"F"T"$6>$B N!*16(&!X[0>:M9!!",4\1R 8`550-``<A>81!
M(7F$01)WA$'MEE%OHD 0Q]^;^!V('T!L^N +9^)AFS;Q3@IJ^[K""'NW[)+9
MV6O\]K<@-DJA:)_+F_#[#61F_QF]#=>&B8A,PE6 Z@_$-!W<./;R_.AQ%@;.
M@FE:%B W@)HKZ?QPAI/1[7AT-YY,ADX-5\)/PT5R<J.Z&0$1EZEV0M@!@HPA
M8)255<[D=]Y7<L?3CP_*ZS?+H33GL#7IL)VYEVPK8!8%%93:5Y?&C@D-?<;K
ME<I:YDRR%)(KO>AY$0'^`[S8"R%7!!5^*)%<8?QB<<9EU;@.."*&-(NI'F]]
M#CZ%,34Y2-)]50/;GUX&58HL[\/6X:(/>5'XU[9SSM%^O\)]+\\I>[K_K)?3
M=MM[D@2HBA!2K@E9V;IV\C",DK*G/_%5[@NF-8_+EQ*:KOF=:TM#A:%2\:.,
M8;$"3:-$B(ODU;Z !=\V;!+;#MMMBZ5[R.57$QN"`-:?P._,?F?V\LQVQ*=Y
M?CWWN(-.EY7;W%;>DC+ NH]'X[R2KXI]#<QMAKBL<O^@1 +8\MDG^%K&[VNO
M$UH6QVF.&U -;#B\G0S[@0O0[>0*C:9FI6-C;)BKU6Y_>F[['X#!S7]02P,$
M% `"``@``[M>,9G9CTM5`0``B0,``!D`>@!#4VAA<G!497-T+T-3:&%R<%1E
M<W0N<VQN4T1E`+P`````" #]&-XJ8V1@:1!A8& P8( `'R!F9 4S646!Q/W4
M=(9]F88>5O4JINM8<,LQ,C$P,#$4,+" I248_C/*,X#$0&H5@(0"F"T"$6>$
MB N!*16(&!X[0>:M9!!",4\1R 8`550-``?66H1!$G>$01)WA$&=D,MN@S 0
M1==!XA\0JU2*D4G(@T47X."JBU95B;HG,$E=N1AA4[5*\^\U@;R:2DVR0/;<
M\9RYW >6ED**A;)>F*P2;L6JRIBP8L$KQ41N4<:A9U%1OB?Z#92R%B<.QJ;Q
M5(HW2%777M$@PEY$,!I@ER+7G0Y02+T084RP1\=^1$.RMF^L6\LF\6M2%C.0
MRNX=5DXJ"\VKQ=4X]/O^Q!L@,AP/D><'&D=&?33R/3? N$\GWFAMFT:G=1#K
M3]OJMN44"L@SR%,&LMY9"*G:EIZ)\NQXS#3VDFG<<3%/N'[77+;H;1Y$Y NV
MK,JD+C;P$K8]/=29PKQ::GESUL(S<$@D:*F]-1:.Z"?;6C>GR_2?'&X[+REG
RE: Firing COM Events from C# Class v-phuang NO[at]SPAM online.microsoft.com (
11/1/2004 7:20:16 AM
Hi

I will research the issue and update you with new information ASAP.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
RE: Firing COM Events from C# Class v-phuang NO[at]SPAM online.microsoft.com (
11/2/2004 3:17:53 AM
Hi Tyler,

Sorry for delay responding.
For how to use ComSourceInterfaces attribute, here is an article, here is
an article, if you still have any concern on this issue, please feel free
to post here.
A COM class wizard for VS.NET 2003
http://www.thecodeproject.com/csharp/CSComTemplate.asp

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: Firing COM Events from C# Class Tyler
11/2/2004 12:53:26 PM
Thanks Peter,

The document you reference describes how to create/hook-up a *new* event
sink in C# that can be used by VB projects, but it doesn't really cover how
to implement one that is defined in VB.

I have managed to come up with something that works, but it requires me to
define the interface (in its entirety) in C#. I do not understand why I
must "re-define" the interface in C# to make it work when my VB source
project has already defined the interface.

For example, I know that if I add the following lines to the top of the
InterfaceTestClass.cs file that it will send the events successfully:

// Step 1: Defines an event sink interface (MyEvents) to be
// implemented by the COM sink.
[GuidAttribute("F258F359-919E-48F3-BA8F-782D99FA6675")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
[ComImport(), ComVisible(false)]
public interface Dummy
{
void MyEvent(string fvsData);
}

[Guid("b05432d9-5a53-4bff-b1dd-68d5fe414f16"),
ComSourceInterfaces(typeof(Dummy)),
ClassInterface(ClassInterfaceType.None)]
public class InterfaceTestClass : MyProject.MyClass
...

However, if I simply add the following lines it doesn't work:

[Guid("b05432d9-5a53-4bff-b1dd-68d5fe414f16"),
ComSourceInterfaces(typeof(MyProject.__MyClass)),
ClassInterface(ClassInterfaceType.None)]
public class InterfaceTestClass : MyProject.MyClass
...

If you look at the type library that is generated in both cases, it is
equivalent (there are not differences):

// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: CSharpTest.tlb

[
uuid(7190690E-409C-37A5-B67C-B9BE9BFB1BD3),
version(1.0),
custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, CSharpTest, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null)

]
library CSharpTest
{
// TLib : // TLib : : {8C51CF60-49E5-4F3E-880E-7E85F6BF67D7}
importlib("MyProject.dll");
// TLib : Common Language Runtime Library :
{BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
importlib("mscorlib.tlb");

// Forward declare all types defined in this typelib

[
uuid(B05432D9-5A53-4BFF-B1DD-68D5FE414F16),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9,
CSharpTest.InterfaceTestClass)
]
coclass InterfaceTestClass {
interface _Object;
interface _MyClass;
[default, source] dispinterface __MyClass;
};
};

So, IMO, this is either a bug or I'm doing something wrong that I do not yet
understand. It seems like a lot of extra work to require developers in C#
to explicitly define event interfaces when they're already defined in
another assembly/dll.

My question now comes down to: Is explicitly defining the event interface
the only way to make this work in C# (for interfaces with a lot of events,
this can be quite cumbersome and error-prone), or is there some way I can
make it work without having to define the event interface in C#?

Thanks, Tyler

Re: Firing COM Events from C# Class v-phuang NO[at]SPAM online.microsoft.com (
11/3/2004 7:41:24 AM
Hi,

So far I am researching the issue and I will give you a response ASAP.
Thanks for you reply!


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: Firing COM Events from C# Class v-phuang NO[at]SPAM online.microsoft.com (
11/5/2004 4:03:57 AM
Hi

Based on my research, we do need to declare the source interface in C# as
the sample I provide before so far. Because now the scenario is that we
wants to expose the Expose the .net event to com client, so the source
interface must be defined in the managed code, that is to say in the
managed metadata. If we imported the source interface from typelibrary, we
may need to modify the IL code which is very tedious and is tend to cause
error.

But the VB.NET has a ComClassAttribute Class, which will simplify the
procedure.
e.g.
[VB.NET]
Imports Microsoft.VisualBasic

<ComClass(TestClass.ClassId, TestClass.InterfaceId, TestClass.EventsId)> _
Public Class TestClass
Public Const ClassId As String = "83B75C2E-C54B-4cb3-9B53-B0AC24555590"
Public Const InterfaceId As String =
"581B36DE-7D3D-4a97-ACAB-AFD556F628CB"
Public Const EventsId As String = "554A893A-F819-4be9-A2B1-2A05CA0A3D5F"
Public Event Ring()
Public Sub FireRing()
RaiseEvent Ring()
End Sub
End Class

[VB6]
Dim WithEvents o As VBNETTest.TestClass

Private Sub Command1_Click()
Set o = New VBNETTest.TestClass
o.FireRing
End Sub

Private Sub o_Ring()
MsgBox "hello"
End Sub

The vb.net compiler will generate the similar metadata code with the C#.
While in C#, we have to define a source interface first and then use the
ComSourceInterfacesAttribute.




Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: Firing COM Events from C# Class Tyler
11/8/2004 11:58:37 PM
Thank you for the information Peter.

I have defined the interface, and everything works well.

Do you know if there is any planned enhancement to the next version of
Visual Studio to make this C# event sink interface definition work
easier/automated/generated?

Thanks, Tyler

Re: Firing COM Events from C# Class v-phuang NO[at]SPAM online.microsoft.com (
11/9/2004 6:53:44 AM
Hi Tyler,

So far I am not sure if the VB.NET's feature will be adopted by C#, but I
think you may try to submit the wish to the MSWish website.
Microsoft offers several ways for you to send comments or suggestions about
Microsoft products. If you have suggestions for product enhancements that
you would like to see in future versions of Microsoft products, please
contact us using one of the methods listed later in this article.

Let us know how we can improve our products.

Product Enhancement suggestions can include:

" Improvements on existing products.
" Suggestions for additional features.
" Ways to make products easier to use.

World Wide Web - To send a comment or suggestion via the Web, use one of
the following methods:

" In Internet Explorer 6, click Send Feedback on the Help menu and then
click the link in the Product Suggestion section of the page that appears.
" In Windows XP, click Help and Support on the Start menu. Click Send your
feedback to Microsoft, and then fill out the Product Suggestion page that
appears.
" Visit the following Microsoft Web site: http://www.microsoft.com/ms.htm
" Click Microsoft.com Guide in the upper-right corner of the page and then
click Contact Us . Click the link in the Product Suggestion section of the
page that appears.
" Visit the following Microsoft Product Feedback Web site:
"http://register.microsoft.com/mswish/suggestion.asp" and then complete and
submit the form.

E-mail - To send comments or suggestions via e-mail, use the following
Microsoft Wish Program e-mail address, mswish@microsoft.com.
FAX - To send comments or suggestions via FAX, use the following Microsoft
FAX number, (425) 936-7329.

Each product suggestion is read by a member of our product feedback team,
classified for easy access, and routed to the product or service team to
drive Microsoft product and/or service improvements. Because we receive an
abundance of suggestions (over 69,000 suggestions a year!) we can't
guarantee that each request makes it into a final product or service. But
we can tell you that each suggestion has been received and is being
reviewed by the team that is most capable of addressing it.

All product or service suggestions received become the sole property of
Microsoft. Should a suggestion be implemented, Microsoft is under no
obligation to provide compensation.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: Firing COM Events from C# Class Tyler
11/9/2004 9:02:44 AM
Thanks, Tyler

AddThis Social Bookmark Button