【问题标题】:DLL dependency question / SetDLLDirectoryDLL依赖问题/SetDLLDirectory
【发布时间】:2011-01-19 20:57:09
【问题描述】:

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

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

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

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

有什么建议吗?

【问题讨论】:

    标签: c++ windows dll installation


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我的问题是我必须延迟加载许多 DLL,而且随着我们集成新的第 3 方模块,该列表经常更改。此外,如果所需的 DLL 不存在,我希望应用程序无法启动,以便我可以修复它(而不是仅在实际尝试使用该 DLL 时才发现)。
      【解决方案3】:

      我认为您最好将 .DLL 文件与 .EXE 放在同一个目录中 - 可能有很多文件,但这可行,而且没有人会在那个目录中查找,所以我也不会担心很多关于它。

      如果您依赖 PATH,那么您总是会任由用户将其搞砸并导致您额外的支持开销,完全没有充分的理由。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2011-10-17
          • 1970-01-01
          • 2014-09-19
          • 1970-01-01
          • 2012-05-23
          • 1970-01-01
          • 1970-01-01
          • 2017-07-12
          • 2020-08-13
          相关资源
          最近更新 更多