Download 2 versions of the same DLL in the same process

I want to do exactly what is described here , but the decision made does not work for me. I believe the reason is explained here :

If a DLL with dependencies is loaded by specifying the full path, the system looks for DLL-dependent DLL files as if they were loaded only with their module names.

If a DLL with the same module name is already loaded into memory, the system only checks the redirection before allowing the loaded DLL, regardless of which directory it is located. The system does not search for the DLL.

I want to have my application in the following structure.

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

My EXE will load DLLs through

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

shared is implicitly loaded in both cases.

I tried the SetDllDirectory parameter, but there is always only one common.dll file.

I added version information in common.dll. c: \ DLL \ common.dll has version 2.0.1.0, and c: \ DLL2 \ DLL2.dll has version 4.0.1.0

I included the following manifest with the corresponding version information, but that did not help.

 <?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> 

Is there a solution to this problem?

+7
source share
1 answer

Where did you build the manifest? EXE or DLL?

You have two main ways to do this: both include the inclusion of the “common” in the private SxS assembly, creating a manifest for it.

Then:

  • If the DLL and DLL2 contain manifests listing the dependent assemblies, then you need to add the dependent assembly to your manifest, specifying "acme.common" (for example) as the dependent assembly. Since dependent assemblies are always searched by default in the loadable modules folder, each DLL will load its own local copy of the shared one.

  • If you simply rely on the default activation context of applications to do most of the hard work, you can try using the ActivationContext API. Call CreateActCtx twice, specifying two two folders as the base folder for the resulting context.

In pseudo code:

 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... 

If the dll libraries already contain their own manifests, the system will use them. If not, this will allow you to specify the search directory for private assemblies without changing the dll itself.


To implement option 1: First, I do not recommend using the dll name as the assembly name. So, create a manifest that looks like this in each folder:

 <!-- 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> 

You can correct the version number to match the version of common.dll in each folder, but that doesn’t matter.

Then either a manifest list or a list, for example, if you are using Visual Studio

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

Just make sure that the versions of the dependent assemblies match the versions of the corresponding acme.common assembly.

+6
source

All Articles