2011-04-14 11 views
9

En mi programa puedo crear objetos COM + dynamicly (finales de unión) utilizandoCom + enlace en tiempo de C# 4.0

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

y luego llamar a uno de estos métodos utilizando la reflexión

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

Funciona greate en .Net 1,1/2,0/3,5

Ahora estoy tratando de ejecutar el mismo código en la misma máquina (Windows XP) compilado para .Net 4.0, pero he conseguido un

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

Tengo la excepción para la mayoría de los objetos Com + (no para todos). ¿Alguien sabe cuál es el problema? ¿Por qué obtengo la excepción en el entorno FW 4.0? ¿Qué debo hacer para evitarlo?

Muchas gracias, Daniel

Después de un poco más de investigación he descubierto que algunos de los servidores proxy COM + se crean como System._ComObject (esos son los nativos, supongo), y algunos son creados como System.Runtime.Remoting.Proxies._TransparentProxy (I piense que esos son objetos .Net Com +). La invocación al método funciona bien para aquellos que se crean como System._ComObject y no funciona para System.Runtime.Remoting.Proxies._TransparentProxy. El hecho más interesante es que en .Net 2.0 todos los objetos se crean de la misma manera (_ComObject y _TransparentProxy) pero la invocación al método funciona bien. Otro hecho interesante es que puedo ver el método de "perdido" en el depurador utilizando reflecton

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

pensé por un momento que podría ser un problema de seguridad, pero ejecuta el código como servicio de windows conectado como usuario con privilegios de administrador

+0

¿Ha comprobado algún problema de 32/64 bits? Tal vez su proceso sea de 64 bits y, por lo tanto, llegue al registro COM de 64 bits (donde nadie vive :-)? –

+0

No creo que sea un problema de 32/34 bits, mi máquina local es de 32 bits, por lo que el servidor remoto –

+0

está bien para 32/64 bits. Ahora, parece que su servidor COM no está en proceso o tiene un modelo de subprocesamiento específico (de ahí los proxies). ¿Puedes dar más detalles sobre esto? ¿están alojados fuera de proceso? En servicios de componentes? ¿Y los argumentos de Invocar? ¿Estás seguro de que no hay ambigüedad? ¿Qué pasa con los BindingFlags? ¿no necesitas Public | Instance? –

Respuesta

6

He descubierto que hay una diferencia entre .NET FW en la creación de tipos de COM, y por lo que yo entiendo, la diferencia solo existe para los objetos COM de .NET. Cuando se crea el tipo de objeto COM con

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

del tipo que se devuelve en .NET 1.1/2.0/3.5 es el tipo de .NET real del objeto, por lo que no hay ningún problema en su invocación de método, pero en .NET 4.0 del tipo System.__ComObject se devuelve lo que el código

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

falla con un método que no se encuentra una excepción.

La solución que he encontrado es la siguiente:

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); 

Este código funciona bien para todos los entornos.

+0

Interesante - De hecho publiqué una respuesta anterior que sospecho que me habría ayudado irónicamente lo borré después de leer otra pregunta que me convenció ¡Me equivoqué! - De todos modos, me alegra que haya solucionado el problema. – Justin

+0

En su código de solución, ¿se supone que 'comObject es lo mismo que' ObjectToActivate'? –

+0

Sí, lo es. ObjectToActivate es una propiedad que devuelve comObject. –

1

No estoy seguro de por qué su código anterior ya no funciona, pero creo que en .NET 4.0 puede llamar a métodos COM utilizando IDispatch/último enlace a través del tipo dynamic - consulte Does C# .NET support IDispatch late binding?.

+0

Pensé en este tipo de solución, pero no es aceptable para mí, porque necesito el mismo código para todas las versiones .Net FW. Es parte de una biblioteca central que se ejecuta en diferentes entornos –

+0

@Daniel: independientemente de si es satisfactoria, ¿sigue mostrando el error el uso de 'dynamic'? – Gabe

+0

He intentado una pequeña muestra con el 'dinámico', funciona (pero inútil para mí (:) –

Cuestiones relacionadas