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._ComO开发者_C百科bject
(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
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.
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?.
精彩评论