DLL dependency question / SetDLLDirectory
I have the following situation and can't come up with any good solution.
I have a C++ application (app.exe) installed in C:\ProgFiles\MyApp. It needs a bunch of DLLs, which I install in C:\ProgFiles\MyApp\bin. I'd like to put them in a subfolder because there are so many of them.
Now when I start app.exe, something needs to let Windows know where the required DLLs are. In the past I was using the PATH environment variable for this, but I can't do this anymore because I will create another application with a separate installer, which uses many of the DL开发者_如何学运维Ls that have the same name.
I was thinking of calling SetDLLDirectory at the beginning of the app - but I forgot that because required DLLs are missing, it fails before getting there.
Any suggestions?
See this article from Microsoft which discusses the DLL search path and related issues.
In particular, notice that if you do not put them in your app’s directory the current directory takes precedence, which is a security hole.
One solution would be to use LoadLibrary
(with a fully-qualified path), then GetProcAddress
. That would be kind of painful.
No normal user is going to go digging around in C:\Program Files\YourApp
and that is where you should put them unless you have a good reason not to.
Using the delay load
option in conjunction with SetDLLDirectory
might work. A delay loaded DLL is dynamically loaded by the system on its first reference. If you are using Visual Studio, you can specify which DLLs are to be delay loaded in the project properties under the Linker Input options. There is a Delay Loaded DLLs
field for specifying them. Otherwise, you can specify /DELAYLOAD:mydll.dll
in the linker command.
I think you are best putting the .DLL files in the same directory as the .EXE - there might be lots of them, but this works and no one is gonna look in that directory anyway, so I wouldn't worry too much about it.
If you rely on PATH then you are always going to be at the mercy of the user screwing it up and causing you extra support overhead, for no good reason at all.
one solution to the problem would be use SetDllDirectory
function; but, it needs to be first thing you execute on your program (which is hard to do), my solution is to use third party program to set dll directory and then invoke your EXE file as a new process:
this is third party which will be a EXE file:
#include <windows.h>
SetDllDirectory(_T(".dll location"));
STARTUPINFOW siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
if (CreateProcessW(L".exe location",NULL, NULL, NULL, FALSE,
0, NULL, NULL,
&siStartupInfo, &piProcessInfo))
{
/* This line waits for the process to finish. */
/* You can omit it to keep going whilst the other process runs */
//dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (SecondsToWait * 1000));
}
else
{
/* CreateProcess failed */
//iReturnVal = GetLastError();
}
return 0;
精彩评论