如何在系统路径之外使用 dll
Posted
技术标签:
【中文标题】如何在系统路径之外使用 dll【英文标题】:How to use a dll outside of the system path 【发布时间】:2012-10-27 11:26:10 【问题描述】:我创建了一个使用 openssl dll(libeay32.dll
和 ssleay32.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的主要内容,如果未能解决你的问题,请参考以下文章