DLL依赖问题/SetDLLDirectory

发布于 2024-10-13 14:18:28 字数 366 浏览 1 评论 0原文

我遇到以下情况,想不出什么好的解决办法。

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

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

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

有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时光匆匆的小流年 2024-10-20 14:18:28

请参阅 Microsoft 的这篇文章,其中讨论了 DLL 搜索路径和相关问题。

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

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

普通用户不会在 C:\Program Files\YourApp 中进行挖掘,这就是您应该放置它们的位置,除非您有充分的理由不这样做。

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.

流云如水 2024-10-20 14:18:28

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

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.

萌梦深 2024-10-20 14:18:28

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

如果您依赖 PATH,那么您总是会受到用户搞砸的支配,并导致您额外的支持开销,而没有任何充分的理由。

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.

等风来 2024-10-20 14:18:28

解决该问题的一种方法是使用 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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文