2011-02-16 11 views
7

Quiero hacer exactamente lo que se describe here, pero la solución aceptada no funciona para mí. Supongo que la razón se explica here:Cargue 2 versiones de la misma DLL en el mismo proceso

Si un DLL con dependencias se carga especificando una ruta completa, el sistema búsquedas de archivos DLL dependientes de la DLL como si estuvieran cargados sólo con sus nombres de los módulos.

Si una DLL con el mismo nombre del módulo se ya cargado en la memoria, el sistema sólo cheques para la redirección y hace un manifiesta antes de resolver a la DLL cargada, no importa en qué directorio que se encuentra. El sistema no buscar para la DLL.

Deseo tener mi aplicación en la siguiente estructura.

c:\Exe 
| 
|----- c:\DLL\DLL.dll, c:\DLL\common.dll 
| 
|----- c:\DLL2\DLL2.dll, c:\DLL2\common.dll 

Mi EXE cargará los archivos DLL a través

LoadLibrary("c:\\DLL\\DLL.dll"); 
LoadLibraryEx("c:\\DLL2\\DLL2.dll"); 

común se carga implícitamente en ambos casos.

Intenté la opción SetDllDirectory, pero siempre hay solo un common.dll cargado.

He agregado la información de versión en common.dll. c: \ DLL \ common.dll tiene la versión 2.0.1.0, mientras que c: \ DLL2 \ DLL2.dll tiene la versión 4.0.1.0

Integré el siguiente manifiesto con la información de la versión correspondiente, pero no fue de ayuda.

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

¿Existe una solución a este problema?

Respuesta

6

¿Dónde ha incrustado el manifiesto? ¿El EXE o los DLL?

Tiene dos formas básicas de hacerlo, ambas implican convertir "común" en un ensamblaje SxS privado creando un manifiesto para él.

continuación:

  1. Si DLL y DLL 2 contienen el listado manifiesta ensamblados dependientes, a continuación, es necesario agregar un dependentAssembly a sus manifiestos que especifican "acme.common" (por ejemplo) como un conjunto dependiente. Como los ensamblados dependientes siempre se buscan, de forma predeterminada, en la carpeta de módulos de carga, cada DLL cargará su propia copia local de común.

  2. Si solo confía en el contexto de activación predeterminado de la aplicación para hacer la mayor parte del trabajo pesado, entonces puede intentar usar la API ActivationContext. Llame al CreateActCtx dos veces, especificando dos las dos carpetas diferentes como la carpeta base para el contexto resultante.

En pseudocódigo:

HACTCTX h1 = CreateActCtx(... for DLL ...); 
HACTCTX h2 = CreateActCtx(... for DLL2 ...); 

ActivateActCtx(h1,...); 
LoadLibrary("C:\\DLL\\DLL1.DLL"); 
DeactivateActCtx(); 
ActivateActCtx(h2,...); 
LoadLibrary("C:\\DLL2\\DLL2.DLL"); 
DeactivateActCtx... 

Si los archivos DLL ya contienen sus propios manifiestos El sistema utilizará los. De lo contrario, esto le permitirá especificar un directorio de búsqueda para ensamblajes privados sin modificar los dll's ellos mismos.


Implementar Opción 1: En primer lugar, no recomiendo tratar de usar el nombre de archivo DLL como el nombre de ensamblado. Por lo tanto, crear un manifiesto que tiene este aspecto en cada carpeta:

<!-- acme.common.manifest --> 
<assembly manifestVersion="1.0"> 
    <assemblyIdentity type="Win32" name="acme.common" version="1.0.0.0" processorArchitecture="x86"/> 
    <file name="common.dll"/> 
</assembly> 

Usted puede fijar el número de versión para que coincida con la versión de common.dll en cada carpeta, pero eso no es importante.

Entonces, o el manifiesto que la lista, o una directiva de este tipo si está utilizando Visual Studio

#pragma comment(linker, "/manifestdependency:\"acme.common'"\ 
        " processorArchitecture='*' version='1.0.0.0' type='win32'\"") 

Sólo asegúrese de que las versiones de montaje dependientes coinciden con las versiones de la asamblea correspondiente 'acme.common'.

+0

Gracias. Integré los manifiestos en las DLL. Entonces, parece que hice lo que recomiendas en 1. ¿O me estoy perdiendo algo? Es el manifiesto correcto? – PeeWee2201

+0

Agregué algunas aclaraciones sobre el método 1. –

+0

Gracias. Lo tengo funcionando. Tuve que cambiar a Windows 7 y usar la herramienta SxsTrace para ver qué está pasando. Una vez que está configurado, es bastante fácil, pero sin la herramienta no tiene visibilidad sobre lo que está mal – PeeWee2201

Cuestiones relacionadas