如何在系统路径之外使用 dll

Posted

技术标签:

【中文标题】如何在系统路径之外使用 dll【英文标题】:How to use a dll outside of the system path 【发布时间】:2012-10-27 11:26:10 【问题描述】:

我创建了一个使用 openssl dll(libeay32.dllssleay32.dll)的应用程序。 使用它们是 indy,我不直接调用 dll。

我发现避免安装程序的最简单的解决方法是:

    把dll作为exe的资源 在程序启动时,我将它们解压到 exe 文件夹中 exe 使用它们

这是完美的,但我想通过在临时文件夹中提取 dll 而不是在 exe 文件夹(在许多情况下是桌面)中提取 dll 来改进方法。

问题是我不知道如何强制应用程序使用临时文件夹中的 dll,因为现在的行为是: 如果 dll 不在当前目录中,请尝试在系统路径中定义的目录中搜索。

谁知道强制 indy 在我的临时路径中使用 dll 的解决方案? (比如“临时注册 dll”)

【问题讨论】:

一种方法是:查看 Indy 是如何加载这些 dll 并修改这些 *.pas 文件并将它们放入您的项目目录中的,那么您就已经走出了困境。 @ComputerSaysNo 我使用 Indy 作为黑盒,我并不懒惰,但我记得有一次我通过在程序启动时“注册”它来了解在系统路径之外使用 dll 的可能性。这对我来说是最好的。可能是 Indy 而不是我使用这些 dll 的事实并不重要。 如果在将 DLL 写入临时文件夹后立即使用 LoadLibrary 显式加载它们,这不满足以后的 LoadLibrary 调用吗? 只是另一个想法:如果您使用 SetEnvironmentVariable 并更改 PATH 变量以使用 DLL 指向您的文件夹...不会欺骗 loadLibrary 使用新路径吗?未经测试的想法:) @DavidHeffernan 如果 lpFileName 不包含路径并且有多个具有相同基本名称和扩展名的加载模块,该函数将返回第一个加载模块的句柄。 【参考方案1】:

您可以使用SetDllDirectory 来操作DLL 搜索顺序。

【讨论】:

+1,但修改 Indy 源代码肯定是最后的手段(这正是我对我的应用程序所做的)。我更喜欢您的解决方案,我认为这是正确的方式。 @kobik 经过反思,我同意。我现在真的很喜欢 frogb 的解决方案,因为我确信它有效。我对LoadLibrary 的工作原理有错误的理解。【参考方案2】:

将 DLL 写入临时文件夹后,立即使用 LoadLibrary 自行加载它们。 这将使 Indy 的 LoadLibrary 在需要时使用您的 DLL:

如果 lpFileName 不包含路径并且有多个 加载具有相同基本名称和扩展名的模块,函数 返回首先加载的模块的句柄。

【讨论】:

我刚刚采用了这个绝妙的想法并将其应用到我的 .net p/invoke 接口单元中,该单元提供了对我的本地库的访问。它使链接更容易。不错。 最后我使用了这个答案 (LoadLibrary) 中建议的技术,这让我在不需要升级 Indy 的情况下成功了,这是一件痛苦的事情(每次我尝试升级我都失败了:太多手动操作)。【参考方案3】:

如果您使用的是最新版本的 Indy 10,IdSSLOpenSSLHeaders 单元有一个公共 IdOpenSSLSetLibPath() 函数来告诉 Indy 在哪个自定义文件夹中查找 OpenSSL DLL:

procedure IdOpenSSLSetLibPath(const APath: String);

【讨论】:

谢谢,在 IdSSLOpenSSLHeaders 单元中无论如何我没有 IdOpenSSLSetLibPath(),意味着我需要更新吗?我有 10.5.8.0 是的,您需要更新,除非您手动修补现有版本。 @RemyLebeau 我正在更新,但我应该相信 SVN 版本吗?它是哪个版本?谢谢 当前主干版本为 10.6.0 rev 5114。 @RemyLebeau 谢谢,我是双重发帖,无论如何我真的被卡住了,我不记得我是如何根据***.com/questions/3204601/… 的说明设法升级 indy 的,是不是有更多的时间升级指示?我现在什至无法找到包裹。

以上是关于如何在系统路径之外使用 dll的主要内容,如果未能解决你的问题,请参考以下文章

如何把文件加入linux系统中

dll隐式链接延迟加载

如何添加默认库路径?

C#的Dllimport能不能调用指定路径的dll文件?

delphi如何获取DLL所在的目录

无法启动此程序,因为计算机中丢失QtCore4.dll。尝试重新安装该程序以解决此问题(在系统里添加3个路径)