Search code examples
c#.netcom+

Com+ late binding c# 4.0


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


Solution

  • 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.