DLL dependency question / SetDLLDirectory

2019-01-26 23:48发布

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

4条回答
叼着烟拽天下
2楼-- · 2019-01-26 23:50

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.

查看更多
疯言疯语
3楼-- · 2019-01-27 00:05

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;
查看更多
手持菜刀,她持情操
4楼-- · 2019-01-27 00:08

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.

查看更多
Animai°情兽
5楼-- · 2019-01-27 00:12

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.

查看更多
登录 后发表回答