Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Com+ late binding c# 4.0

Tags:

c#

.net

com+

In my program I create Com+ objects dynamicly (late binding) using

Type comObjectType = Type.GetTypeFromProgID(progId, true); 
object comObject = Activator.CreateInstance(comObjectType); 

And then call one of the methods using reflection

object result = comObjectType.InvokeMember(MethodToActivate, BindingFlags.InvokeMethod, null, comObjec, new object[] {....});

It works greate in .Net 1.1/2.0/3.5

Now I'm trying to run the same code on the same machine (Windows XP) compiled for .Net 4.0, but I've got a

Exception: Method 'System.__ComObject.{MethodName}' not found. 

I've got the exception for most of Com+ objects (not for all). Does anybody know what is the problem? Why do I get the exception in FW 4.0 environment? What should I do to avoid it?

Thanks a lot, Daniel

After some more investigation I have discovered that some of the Com+ proxies are created as System._ComObject (those are the native ones, I suppose), and some are created as System.Runtime.Remoting.Proxies._TransparentProxy (I think that those are .Net Com+ objects). Method invocation works fine for those that are created as System._ComObject and does not work for System.Runtime.Remoting.Proxies._TransparentProxy. The most intersting fact is that in .Net 2.0 the all the objects are created in the same way (_ComObject and _TransparentProxy) but the method invocation does work fine. Another interesting fact is that I can see the "missing" method in the debugger using reflecton

((System.EnterpriseServices.RemoteServicedComponentProxy)((((System.Runtime.Remoting.Proxies.__TransparentProxy)(ObjectToActivate)))._rp)).ProxiedType.GetMethods()

I thought for some moment that it could be a security issue, but I run the code as WindowsService logged on as a user with Administrator privileges

like image 966
Daniel Kabzon Avatar asked Apr 14 '11 06:04

Daniel Kabzon


2 Answers

I have discovered that there is a difference between the .NET FW in COM type creation, and as far as I understand the difference exists only for .NET COM objects. When the COM object type is created with

Type comObjectType = Type.GetTypeFromProgID(progId, true);

the type that is returned in .NET 1.1/2.0/3.5 is the actual .NET type of the object, so there is no problem in its method invocation, but in .NET 4.0 the System.__ComObject type is returned so the code

result = comObjectType.InvokeMember(
   MethodToActivate, BindingFlags.InvokeMethod, null, ObjectToActivate, InputParams);

fails with a method not found exception.

The solution that I have found is the following:

Type comObjectType = Type.GetTypeFromProgID(progId, true);        
object comObject = Activator.CreateInstance(comObjectType);

// here the real object type is returned
Type acctualObjectType = comObject.GetType();
result = acctualObjectType.InvokeMember(
   "MethodToActivate", BindingFlags.InvokeMethod, null, comObject, InputParams);

This code works fine for all environments.

like image 134
Daniel Kabzon Avatar answered Oct 11 '22 00:10

Daniel Kabzon


I'm not sure why your previously running code no longer works however I believe that in .Net 4.0 you can call COM methods using IDispatch / late binding via the dynamic type - see Does C# .NET support IDispatch late binding?.

like image 40
Justin Avatar answered Oct 11 '22 02:10

Justin