Pregunta

Estamos adaptando nuestro cliente lado de aplicación relativamente complicado (ActiveX / .NET / Delphi / C ++ / COM) para utilizar SxS para lograr el despliegue no admin y el aislamiento de las versiones anteriores de nuestro producto.

Hemos sido capaces de lograr este objetivo por casi todos nuestros componentes en Proc como nuestra interfaz de usuario de .NET, Delphi interfaz de usuario y los servidores COM que utilizamos en proc componiendo un archivo de manifiesto que describía todas las librerías utilizadas por nuestro proceso, sin registro en el cliente de cualquiera de los componentes (casi).

Y aquí viene la parte casi: Por el momento, nuestros invoca la aplicación (del que es c ++ porción) una salida de servidor ActiveX proc (Delphi EXE), que a su vez sí invoca otro conjunto de salida de los servidores ActiveX proc (plugins de terceros, cualquier cosa va aquí, Delphi, C ++, cualquier cosa con tal de que está fuera de proc EXE e implementa nuestras interfaces).

Como sabemos SxS no admite servidores de ActiveX proc. Y no podemos usar estos objetos como en servidores proc com en nuestro proceso principal, ya que requeriría una reescritura importante de nuestra aplicación e incluso peor, un descanso de nuestra API orientada al público que es utilizado por las herramientas de terceros y proveedores, una API ruptura que no podemos permitir.

Hemos tropezado con este artículo que describe cómo IHTMLDocument2 se puede extraer de un Internet Explorer ventana que se ejecuta en un proceso independiente. Que nos hizo pensar de este enfoque:

Nos gustaría crear una aplicación vía satélite / proceso secundario que se desarrollará el ActiveX como en el servidor de procesos. A continuación, vamos a utilizar LresultFromObject y ObjectFromLresult para transferir una referencia del objeto ActiveX desde el satélite aplicación al proceso principal de la aplicación. La aplicación satélite tendrá su propio archivo de manifiesto que permitirá que se ejecute en modo SxS.

Se tomará

El mismo enfoque para comunicarse entre esta Delphi EXE y el tercero AciveX EXE plugins

No es una solución alternativa, que por el momento no preferimos sobre la solución propuesta por encima del cual es el uso remoto de .NET y .NET com clases de proxy para abrir el canal de comunicación entre los dos procesos, mediante la traducción de la solicitud com a remota de .NET, y de nuevo a com en el segundo proceso.

Así que aquí viene la pregunta:

  1. ¿Qué opinas acerca de este enfoque?
  2. ¿Ves una mejor solución al problema?
¿Fue útil?

Solución

Es posible hacerlo. Lo que se necesita:

  • Una aplicación necesita para iniciar un servidor propio lugar de depender de COM para hacerlo. No es necesario el direccionamiento indirecto adicional proporcionada por el registro, sólo tiene que utilizar CreateProcess ().
  • Un servidor debe registrar sus fábricas de clase en su método main () con CoRegisterClassObject ().
  • Importante: el CLSID se utiliza para cada fábrica debe ser alterada para ser único para cada instancia de servicio. Esto asegura que el cliente se conecta al servidor correcto. Yo simplemente XOR el ID de proceso con un CLSID generador de clases. El cliente conoce el ID del proceso, así que puede hacer la misma alteración.
  • La aplicación debe llamar a CoCreateInstance () en un bucle con una llamada Sleep () para esperar a la factoría de objetos a aparecer. No declare fracaso hasta al menos 60 segundos han pasado (que me bits).
  • Tanto la aplicación y el servidor necesitan un manifiesto que contiene un elemento <file> para cada proxy / DLL stub y <comInterfaceExternProxyStub> elementos para cada interfaz que se remoted.

Otros consejos

Alex,

nobugz es adecuado, se puede acceder a la tabla de objetos en ejecución para crear una instancia de un objeto COM de un proceso en ejecución de su exe automatización de Delphi.

Sin embargo, he encontrado un gran problema que no puedo explicar. Sólo puedo acceder al objeto a través del método de la variante de despacho cuando se trabaja de esta manera.

Básicamente si mi exe Active X no está registrado, me sale un error "Interfaz no compatible" si trato de instancia del objeto a través de interfaces, por ejemplo:

WebUpdate: IAutomation;

WebUpdate: = CoAutomation.Create; <- no trabajará error


WebUpdate: Variante;

WebUpdate: = CreateOleObject ( 'WebUpdate.Automation'); <- Obras Bellas

Si registro el EXE activo utilizando regserver el problema desaparece !!

Va la figura!

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