2010-10-19 26 views
10

Estoy tratando de configurar el COM libre de registro, pero tengo un pequeño problema porque otro objeto COM puede ser el cliente.Registro Com y dll manifiestos

App.exe -----> servidor COM/Client DLL (registrados o no) --------> COM DLL de servidor (no registrado)

Mi pregunta es, ¿es posible para crear un manifiesto para el segundo dll (servidor COM/cliente dll)? No tengo control del ejecutable, pero si lo hiciera, esto funciona si creo un manifiesto de cliente para el ejecutable y un manifiesto de servidor para el dll del servidor COM.

este es el archivo de manifiesto para el dll intermedio. Intenté incrustarlo y lo intenté de forma externa. Aún no funciona.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity type="win32" 
        name="COMCliSer.dll" 
        version="1.0.0.0" 
    /> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
        name="COMSer.dll" 
        version="1.0.0.0"      
     /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

En una investigación adicional, que puede conseguir todo esto funcione, siempre que el DLL medio está también libre de registro y el exe tiene un manifiesto de aplicación. Tan pronto como registre el dll intermedio y abandone el manifiesto de la aplicación (no tengo control de qué exe usará mi dll), todo deja de funcionar.

Si el exe no tiene manifiesto, entonces el manifiesto de dll no se tiene en cuenta. Puedo probar esto al configurar todo para que funcione. Luego, poner un error en el manifiesto de la asamblea. Esto muestra el mensaje habitual:

No se puede crear el proceso: esta aplicación no se ha podido iniciar porque la configuración de la aplicación es incorrecta. Reinstalar la aplicación podría resolver el problema.

Si a continuación, colocar el manifiesto de aplicación, se carga la aplicación (aunque el CoCreateInstance falla porque las dependencias no se tienen en cuenta)

+0

¿por qué llama el conjunto 'comser.dll'? ¿La información del manifiesto de la asamblea se fusionó? Es mucho más fácil implementar un ensamblado con un nombre descriptivo, p. "Microsoft.VC90.CRT", que contiene dll con diferentes nombres: "msvcr90.dll". Cuando se trata de conjuntos dll, se vuelve más difícil depurar ya que un único manifiesto ahora tiene dos propósitos: describir el contenido del ensamblado a los consumidores, Y describir las dependencias del archivo DLL en el ensamblado. –

+0

¡Los nombres han sido cambiados para proteger a los inocentes! Esos no son los nombres reales. Son dlls COM nativos y no ensamblados .NET. – Steve

+0

Además, ¿con qué "no funciona" cuenta? ¿El exe y el 2nd dll cargan y simplemente fallan al instanciar el 3ro, o el exe, o 2nd dll no se carga por completo? Hacer que las cosas realmente no se carguen es un buen paso, ya que significa que el sistema está viendo el manifiesto y registrando un error en el sistema, o en la aplicación, al menos en el registro de eventos. Si simplemente está fallando en la llamada a CoCreateInstance, entonces probablemente no pueda ver el manifiesto en absoluto. –

Respuesta

5

Sólo tiene que añadir una dependencia conjunto a la/el manifiesto del DLL del cliente de servidor que apunta a la com servidor dll.

Recuerde que los manifiestos de ensamblaje son diferentes a los manifiestos de 'aplicación': un manifiesto de ensamblaje describe un conjunto: le da un nombre y enumera sus dlls. Un manifiesto de aplicación es el recurso integrado RT_MANIFEST, que describe las dependencias de los módulos actuales.

Así, en el análisis final, tendría que:

  • app.exe, con una externa (app.exe.manifest) o RT_MANIFEST incrustado que describe una dependencia de un montaje llamado 'acme.clientserver'
  • acme.clientserver.manifest describiendo un ensamblado y listando 'clisrv.dll' como un dll libre de registro.
  • clisrv.dll, con una externa (clisrv.dll.2.manifest) o incrustado RT_MANIFEST, que describe una dependencia de un conjunto llamado 'acme.server'
  • acme.server.manifest, que describe un ensamblaje, lista serv .dll como una aplicación gratuita de registro.
  • serv.dll - que puede, o no, a su vez tener una lista de manifiesto aún más conjuntos dependientes.

Es técnicamente posible llamar a la asamblea por el nombre del archivo DLL, y combinar tanto el montaje como dll manifestar juntos - el cargador de Win32 soporta esto, pero algunos parámetros que son válidos en manifiestos de aplicación no son válidos en los manifiestos de montaje , lo que puede provocar que el ensamblaje resultante no se cargue. También hace que sea muy difícil firmar digitalmente.


WRT el exe tiene que tener un manifiesto: Por lo general, el manifiesto del ejecutable configura el contexto de activación por defecto del proceso. No estoy 100% seguro de cómo se comporta Windows cuando el archivo ejecutable no tiene manifiesto, pero estoy bastante seguro de que los manifiestos en dlls se seguirán procesando.

Lo que significa que el problema se reduce a la falta de soporte de aislamiento en CoCreateInstance, por alguna razón, de forma predeterminada, CoCreateInstance solo busca en el contexto de activación predeterminado para las entradas com gratuitas.

La forma de anular que es construir manualmente su propio contexto de activación, mediante el Activation Context API

El método básico sería llamar:

  • CreateActCtx - para crear un contexto de activación de archivos DLL se manifiestan .
  • ActivateActCtx - para activar el contexto
  • CoCreateInstance - Ahora buscará el contexto de activación actual para las entradas de com reg free.
  • DeactivateActCtx - para restaurar el contexto de activación predeterminado.

Puede añadir/D ISOLATION_AWARE_ENABLED para envolver la mayoría de las llamadas ventanas que se efectúan por los contextos de activación, por alguna razón no se ajusta a CoCreateInstance:/

+0

no tengo el app.exe.manifest (no lo necesito ya que está registrado el dll medio). Traté de agregar un manifiesto a la dll del medio, pero fue en vano. – Steve

+0

¿Ha abierto el dll intermedio en un editor de recursos (por ejemplo, Visual Studio) y ha visto si tiene un recurso RT_MANIFEST y qué hay en él? VS siempre muestra RT_MANIFESTS como hexadecimal, por lo que debe exportarlo para verlo como texto. –

+0

Bien, hecho eso. El dll tiene dos RT_Manifiestos, uno que supongo que fue puesto allí por el compilador (Delphi) nombrando los Controles Comunes de Windows como una dependencia, y el otro 1, el que agregué que se muestra arriba. – Steve

Cuestiones relacionadas