DLL依赖问题/ SetDLLDirectory

时间:2011-01-19 20:57:10

标签: c++ windows dll installation

我有以下情况,无法提出任何好的解决方案。

我在C:\ ProgFiles \ MyApp中安装了一个C ++应用程序(app.exe)。它需要一堆DLL,我安装在C:\ ProgFiles \ MyApp \ bin中。我想将它们放在子文件夹中,因为它们有很多。

现在,当我启动app.exe时,需要让Windows知道所需DLL的位置。在过去,我正在使用PATH环境变量,但我不能再这样做,因为我将使用单独的安装程序创建另一个应用程序,该安装程序使用许多具有相同名称的DLL。

我正在考虑在应用程序的开头调用SetDLLDirectory - 但我忘记了因为缺少所需的DLL,它在到达之前就失败了。

有什么建议吗?

4 个答案:

答案 0 :(得分:4)

delay load选项与SetDLLDirectory结合使用可能会有效。延迟加载的DLL由系统在其第一个引用上动态加载。如果您使用的是Visual Studio,则可以在“链接器输入”选项下的项目属性中指定要延迟加载的DLL。有一个Delay Loaded DLLs字段用于指定它们。否则,您可以在链接器命令中指定/DELAYLOAD:mydll.dll

答案 1 :(得分:4)

请参阅Microsoft的this article,其中讨论了DLL搜索路径和相关问题。

请注意,如果您不将它们放在应用程序的目录中,则当前目录优先,这是一个安全漏洞。

一种解决方案是使用LoadLibrary(使用完全限定的路径),然后使用GetProcAddress。那会很痛苦。

没有普通用户可以在C:\Program Files\YourApp进行挖掘,除非你有充分的理由不这样做,否则你应该把它们放在那里。

答案 2 :(得分:2)

我认为你最好将.DLL文件放在与.EXE相同的目录中 - 可能有很多这些文件,但是这样可行并且无论如何也没有人会查看该目录,所以我也不会担心很多。

如果您依赖PATH,那么您总是会受到用户的怜悯,并且会给您带来额外的支持开销,完全没有理由。

答案 3 :(得分:0)

问题的一个解决方案是使用SetDllDirectory函数;但是,它需要首先在你的程序上执行(这很难),我的解决方案是使用第三方程序设置dll目录,然后调用你的EXE文件作为一个新进程:

这是第三方,它将是一个EXE文件:

#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;
相关问题