从程序启动另一个目录加载DLL(Load a DLL from another directory

2019-07-29 10:19发布

我的基本问题是这样的:我的程序(MyProgram.exe)对从另一个程序(OtherProgram)一个DLL的依赖,而我试图避免重新包装一个新的DLL每次OtherProgram更新。 我想在OtherProgram的DLL MyProgram.exe链接,当它启动,但我不能完全确保Windows允许这一点。 所以,如果有某种解决办法的,这也将是可以接受的。

而只是一些背景,该平台是Windows 7 x64和MyProgram.exe当我创建的MyProgram.exe项目目录符号链接到OtherProgram的安装目录下的DLL运行正常。 当我尝试无符号链接运行它,我得到了“程序无法启动,因为OtherProgramDLL.dll从计算机中缺少”的错误。

任何意见或链接到相关信息,非常感谢!

编辑:澄清:该DLL没有在编译时挂钩,这个问题在运行起来的作物

Answer 1:

有两种类型的在Windows世界动态链接:

  1. 负载时间链接就是当你的程序启动DLL被自动加载。 Windows发现使用特定的算法,我将在下面讨论这个DLL。
  2. 运行时链接是当明确通过调用加载DLL LoadLibrary在你的代码。 类似的规则适用的图书馆是如何发现的,但您可以指定控制搜索完全合格的或相对合格的路径。

在加载时链接的情况下 ,MS建议你的程序的DLL文件都存储在并从您的应用程序从加载同一个目录中加载。 如果这是在所有可行的,这可能是你最好的选择。

如果还是不行,还有其他几个选项, 这里列出 。 一种是通过将DLL无论是在工作目录或申请被从装载目录利用搜索顺序。

您可以更改应用程序的工作目录:

  1. 创建一个快捷方式到您的应用程序。
  2. 调出快捷方式的属性
  3. 编辑与该DLL所在的目录“开始的”属性。

当您使用快捷方式启动应用程序,它会加载正确的DLL。

负载时链接的其他选项包括:

  • 添加一个清单给你的应用程序,它指定了您的相关组件是,或者,
  • 设置PATH


Answer 2:

您可以添加该DLL所在的目录PATH环境变量。



Answer 3:

你可以使用调用LoadLibrary ,但你会需要一种方法来保证DLL的位置。 这篇Wikipedia 文章提供了有关它已被加载后如何使用DLL很好的例子。



Answer 4:

我一直在努力与同样的问题,也发现了类似的建议的方法是死路一条LoadLibrarySetDllDirectory ,Qt的addLibraryPath等。 无论什么样的我试过了,问题仍然存在,如应用程序检查库(并没有发现他们)实际运行的代码之前,因此任何代码的解决方案注定要失败的。

我几乎绝望了,但后来发现了一个非常容易的办法,也可能是像你这样的情况下有所帮助: 使用批处理文件! (或实际应用之前类似的加载器)

对于这样的目的Windows批处理文件看起来是这样的:

@echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>

/编辑:刚才看到@SirDarius在评论Luchian的答案 ,它描述的是这样,所以只是把我的批处理代码位作为参考,所有学分到他家里去。



Answer 5:

使用符号链接到第三方可执行文件

我发现所倡导的方法亚伦Margosis有用。 看到:

使用NTFS路口修正在Windows的64位版本的应用程序兼容性问题

从本质上讲,创建符号链接到每个相关的第三方可执行文件。 将这些符号链接文件,并在当中自己依赖的可执行文件。 除了文件名更改为目标,在“软”的符号链接将解决加载时的依赖甚至链接的目标是通过未来的更新变化。



Answer 6:

我有一个应用程序我工作的同样的问题。

我不想使用运行时加载,因为有几十功能,我需要手动创建函数指针。

清单文件的Dibling先生的提开了一扇新的大门,但我遗憾的是发现了支持该功能的窗口的最古老的版本的Windows 7,它甚至不会在Vista上工作。

长话短说,熟悉Windows应用程序开发的朋友告诉我查找延时加载的DLL ,这原来是用最小的努力完美地解决这个问题。 它延迟DLL库加载到要么你做手工点,或第一次的函数被调用。 所以,你只需要您的DLL路径发生之前,在添加到搜索路径SetDllDirectory会有所帮助。

这是使它工作的步骤:

(连接器 - > VS2015的输入)1)指定的DLL将被延迟加载到接头,或者通过生成文件,cmake的或VS属性页

2)调用SetDllDirectory会在程序的开始,是由该DLL任何调用之前。

延迟加载的DLL支持回VC6的所有道路。 SetDllDirectory会是XP SP1之后的支持。



文章来源: Load a DLL from another directory at program start