我有以下情况,无法提出任何好的解决方案。
我在C:\ ProgFiles \ MyApp中安装了一个C ++应用程序(app.exe)。它需要一堆DLL,我安装在C:\ ProgFiles \ MyApp \ bin中。我想将它们放在子文件夹中,因为它们有很多。
现在,当我启动app.exe时,需要让Windows知道所需DLL的位置。在过去,我正在使用PATH环境变量,但我不能再这样做,因为我将使用单独的安装程序创建另一个应用程序,该安装程序使用许多具有相同名称的DLL。
我正在考虑在应用程序的开头调用SetDLLDirectory - 但我忘记了因为缺少所需的DLL,它在到达之前就失败了。
有什么建议吗?
答案 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;