Redirecting dependant DLLs in the manifest for a plugin DLL
For anyone else with the same problem, I eventually solved this by marking all the secondary DLLs as delayload, and then having the delayload helper function load from the directory of the primary DLL.
DLL redirection - working in XP, not in Windows 7
So it turns out that Windows platforms from Vista onwards do some activation context caching, i.e. a manifest is looked for the first time the application runs. If a manifest is added or changed after the first run, Windows doesn't bother to look for it to save time loading.
So my scenario does work, but you need to force Windows to re-cache the activation context by modifying the applications binary (e.g. the time-stamp).
I tried that and my user32.dll is loaded in Windows 7 from the application directory.
Refs:
http://blogs.msdn.com/b/vistacompatteam/archive/2006/11/13/manifest-and-the-fusion-cache.aspx
VB6 Manifest not working on Windows 7
Altering DLL search path for static linked DLL
My first thought is, if you are statically linking a dll, it isnt a plugin. Just put the dll in the EXE folder and be done with it. That is the deployment configuration supported by windows for statically loaded DLLs.
That said, there are ways to achieve what you want. But they are mostly stupid, or complicated for no good reason: Your options are:
- Don't statically link. Use LoadLibrary("plugins/Plugin.dll") & GetProcAddress to access plugin content.
- Add "the path to your plugins folder" to the systems PATH environment variable.
- Use the delay load mechanism to delay accessing the plugins functionality, set a custom helper function that can load the dll(s) using a provided path.
- Turn the plugins folder into an assembly (by creating a .manifest file in it that lists the plugin.dll). Add "plugins" as a dependent assembly to your app. Now it will look in the plugins folder.
- Split your application into a stub exe and a dynamically loaded part. In the stub exe call SetDllDirectory to point to the plugin folder, then call LoadLibrary passing the full path to "appstub.dll".
To turn a folder, with one or more dll's into an "assembly", simply add a file to the folder with the folders name.manifest.
So, plugins.manifest :-
<assembly manifestVersion="1.0">
<assemblyIdentity type="Win32" name="Plugins" version="1.0.0.0" processorArchitecture="x86" />
<file name="Plugin.dll"/>
</assembly>
It is a VERY good idea to ensure that the folder and the dll's name is different as if the dll name is the assembly name windows starts looking at its embedded manifest file for information about the assembly.
Assuming you are using Visual Studio 7 or later, the following directive added to a .c/.cpp or .h file in the project will then make your application attempt to load dlls from the assembly rather than just the local directory:
#pragma comment(linker, "/manifestdependency:\"name='Plugins' "\
"processorArchitecture='*' version='1.0.0.0' "\
"type='win32'\"")
Related Topics
Set Precision of Std::To_String When Converting Floating Point Values
Getline Not Working Properly? What Could Be the Reasons
I'Ve Heard I++ Isn't Thread Safe, Is ++I Thread-Safe
In What Ways Do C++ Exceptions Slow Down Code When There Are No Exceptions Thown
Very Poor Boost::Lexical_Cast Performance
How to Generate a Random Double Uniformly Distributed Between 0 and 1 from C++
Is There a Linq Library for C++
Catching Exceptions from a Constructor's Initializer List
Does the C++ Volatile Keyword Introduce a Memory Fence
What Do C and Assembler Actually Compile To
Compile the Python Interpreter Statically
How to Scale Down Numbers from Rand()
What Is Uint_Fast32_T and Why Should It Be Used Instead of the Regular Int and Uint32_T
How to Create a Pause/Wait Function Using Qt
Fast N Choose K Mod P for Large N
Use of Min and Max Functions in C++