I'm racking my brain trying to come up with an elegant solution to a DLL load problem. I have an application that statically links to other lib files which load DLLs. I'm not loading the DLLs directly. I'd like to have some DLLs in another folder other than the folder that the executable is in. Something like %working_folder%\dlls - I'd rather not have dozens (yes ... dozens) of DLLs in my %working_folder%.
I'm trying to develop something that is part of the main app that will adjust the search path @ startup. The problem I'm running into is that this new custom DLL path isn't in the system search path. When I start the app it crashes (STATUS_DLL_NOT_FOUND) because the necessary DLLs are not in the appropriate places. What I'd like to do is to check @ startup if this new custom DLL folder is in the process environment variable search path and if not add it. Problem is, the application attempts to load all these DLLs before the app executes one line of code.
How do I fix this? I've considered writing a help app that starts first, adjusts the environment variables appropriately and the launches the main app via CreateProcess. This will work I'm sure of it but it makes things difficult on the developers. When they debug the main app they're not going to launch a helper app first - not that they could even do that.
I've tried the registry app path feature with no success. Same chicken and egg problem as before.
What can I do here?
[Edit - after re-reading the question I see that the problem you're having is that the DLLs are getting loaded before
main
starts]I'm guessing that those libraries are written in C++ and are loading the DLLs from the constructor of some objects in global scope. This is problematic. Allow me to quote Yossi Kreinin:
[Original answer below]
See this page for the search algorithm used for loading DLLs. You can use
SetDllDirectory()
to add a directory to the DLL search path.You also should be able to add a directory to the PATH environment variable using
GetEnvironmentVariable()
andSetEnvironmentVariable()
.Another option is to change the current working directory to the folder containing the DLLs with
SetCurrentDirectory()
. Just make sure to change the working directory back after loading the DLLs if you ever load any files using relative filenames.I found Matthew's answer worked for me.
In visual studio 2012 goto your project properties and in Configuration Properties->Linker->Input->Delay Loaded Dlls add each dll file that you want to not load until needed.
Although it no longer needs to run before main, this is my code to set the new search path
My recommendation is to use delayload linking for the DLLs and call SetDllDirectory() early enough so it can find them when the methods/functions are invoked.