We have an application that depends on a number of groups of third-party DLLs. Unfortunately, none of the writers of these third-party DLLs have named them very consistently so it is hard to see which DLL is part of what group.
To try and manage this, we would like to put groups of third-party DLLs in a folder in our application folder rather than along-side the application something like this.
--> Application Folder
--> Application.exe
--> MyDLL1.dll
--> MyDLL2.dll
--> Third Party 1 DLL folder
--> Third Party 1 DLL 1.dll
--> Third Party 1 DLL 2.dll
--> Third Party 1 DLL 3.dll
--> Third Party 2 DLL folder
--> Third Party 2 DLL 1.dll
--> Third Party 2 DLL 2.dll
--> Third Party 2 DLL 3.dll
My question is how to get the dynamic linker to find them and load them?
We could do this manually with LoadLibrary() and GetProcAddress(), however this is intensely tedious. It looks like we might be able to do this with manifests and "probing", but this seems to be Windows 7 only (we need to work on XP and above).
Update
We used manifests to do this in the end (thanks @Chris) - there were a couple of other hoops we had to jump through in case anyone is looking for a solution!
First, our "assembly" actually has several DLLs, one that we link to that then links to others. All of these DLLs will need the assembly dependency adding to their manifests (you can use mt.exe to do this without having access to the the source code of these DLLs).
Second, the assembly needs to go alongside the DLL, not alongside the EXE - our DLL was actually a plugin that was already in a subfolder of the app.
Here is our final layout:
--> Application Folder
--> Application.exe
--> Plugins folder
--> MyDLL1.dll
--> Third Party 1
--> Third Party 1.manifest
--> A.dll
--> B.dll
--> C.dll
If MyDLL1.dll is a plugin that links to A.dll, and A.dll links to both B.dll and C.dll then:
For me, (3) is a bit irritating. You would think that the linker would look in the assembly for dependent DLLs.
You can do it with manifests without probing. Create "fake" assemblies - by defining .manifests, that contain the dlls. (No change is requried in the dll's for this) Since assembly support was added to NT 5.1 (Windows XP) the windows loader first looks for assemblies by scanning for a folder with the assemblies name.
So, for example, if you need to distribute the Microsoft Visual C runtime for Visual C 2008 with your application, you could create a folder structure that looks like this:
--> Application Folder
--> Application.exe
--> MyDll1.dll
--> MyDll2.dll
--> Microsoft.VC90.CRT
--> Microsoft.VC90.CRT.manifest
--> msvcr90.dll
--> msvcp90.dll
--> msvcm90.dll
This same scheme would work for your 3rd party dlls. All you would then need to do would be to add the "fake" assemblies as dependent assemblies to your application's manifest (if your dlls have manifests, (and they access the 3rd party dlls) then their manifests will have to have entries too.
The manifest files describing the assemblies need an assemblyIdentity, and a file node per dll:
<assembly manifestVersion="1.0">
<assemblyIdentity type="Win32" name="Assembly Name" version="1.0.0.0" processorArchitecture="x86" />
<file name="dll1.dll" />
<file name="dll2.dll" />
</assembly>
And your application, and dlls are built with MS Visual Studio 2005 or later, the following pragma directive would make your app look for the dlls in the assemblies:
#pragma comment(linker, "/manifestDependency:\"name='Assembly Name' processorArchitecture='*' version='1.0.0.0' type='win32' \"")
You can use SetDLLDirectory function to specify path(s) for your DLLs. Alternatively read information about using application-specific paths.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With