Cómo hacer que COM sin registro funcione en interoperabilidad administrada / no administrada

StackOverflow https://stackoverflow.com/questions/5392152

  •  28-10-2019
  •  | 
  •  

Pregunta

Tengo un objeto COM en proceso de C ++ / ATL no administrado (en Unmanaged.dll) que estoy tratando de usar desde una DLL C # administrada (Managed.dll). Sin embargo, quiero usar COM sin registro. Lo tengo en estos pasos:

  • Registre el objeto COM en la máquina de desarrollo. El servidor en proceso debe tener una biblioteca de tipos debidamente registrada.
  • Agregue una referencia al objeto COM dentro del proyecto C # y luego establezca Propiedades de referencia en Aislado= Verdadero.

Esto produce Unmanaged.dll, Managed.dll y Native.Managed.manifest. Al abrir el manifiesto, queda bastante claro cómo lo usa el sistema para cargar el objeto COM sin necesidad de registro.

Aquí está el problema. Tengo un EXE administrado (Managed.exe) que carga Managed.dll dinámicamente para acceder a tipos públicos. Lo que quiero decir con "dinámicamente" es que utiliza Assembly.LoadFrom ("Managed.dll"). Cuando el código dentro de Managed.dll intenta crear el objeto COM, obtiene una excepción de "clase no registrada". Parece que el contexto de activación no se configura correctamente cuando se carga Managed.dll.

¿Hay alguna forma de hacer que COM sin registro funcione en este escenario?

¿Fue útil?

Solución

Dos días sin respuesta, así que esto es lo que se me ocurrió en ese tiempo ...

De hecho, parece que el contexto de activación lo configura el sistema operativo en el inicio del proceso en función del manifiesto asociado con el EXE principal. Eso significa que todos los elementos relacionados con COM sin registro deben estar en Main.exe.manifest en el momento en que se inicia el proceso. Esto rompe el aislamiento entre EXE y DLL. Si una DLL es responsable de la creación de objetos COM, no esperaría que el manifiesto EXE tuviera que contener la información COM sin registro. Es posible que haya esperado que el manifiesto asociado con la DLL se fusionara en el contexto de activación del proceso en el momento en que se carga la DLL, pero no es así.

Para solucionar esto, la DLL debe configurar un nuevo contexto de activación antes de crear el objeto COM. Para empeorar las cosas, actualmente (a partir de .NET 4.0) no existe una forma administrada de hacer esto. Por lo tanto, la DLL deberá PInvokear las siguientes funciones de Win32:

Envolví estas llamadas con una clase administrada que llama a CreateActCtx y ActivationActCtx en el constructor y DeativateActCtx y ReleaseActCtx en IDisposable :: Dispose.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top