更改静态链接 DLL 的 DLL 搜索路径
我已经搜索了如何执行此操作的任何提示,但我发现的只是如何将 SxS DLL 重定向到本地应用程序文件夹。 这是我想要完成的任务: (C++) Application.exe 链接到 DLL、Plugin.DLL(依赖项目)。该 DLL 不放置在应用程序目录中,而是放置在名为“plugins”的子文件夹中。由于 DLL 是静态链接的,应用程序将尝试从应用程序文件夹加载它。
有什么办法可以更改这个特定 DLL 的搜索路径吗?通过清单还是 VS2008 链接器配置?
I've searched for any hints how I can do this, but all I found was how to redirect a SxS DLL to the local application folder.
Here is what I want to accomplish:
The (C++) Application.exe is linked to a DLL, Plugin.DLL (dependant project). This DLL is not placed inside the application directory, but in a subfolder called "plugins". As the DLL is statically linked, the application would try to load it from the application folder.
Is there any way how I can change the search path for this particular DLL? Either through manifests or VS2008 linker configurations?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的第一个想法是,如果你静态链接一个 dll,那么它就不是一个插件。只需将dll放入EXE文件夹中即可完成。这就是windows支持的静态加载DLL的部署配置。
也就是说,有一些方法可以实现您想要的目标。但它们大多是愚蠢的,或者没有充分理由的复杂:你的选择是:
要将包含一个或多个 dll 的文件夹转换为“程序集”,只需将一个文件添加到文件夹名称为 .manifest 的文件夹中即可。
因此,plugins.manifest:-
确保文件夹和 dll 的名称不同是一个非常好的主意,就好像 dll 名称是程序集名称一样,Windows 开始查看其嵌入的清单文件以获取有关程序集的信息。
假设您使用的是 Visual Studio 7 或更高版本,添加到项目中的 .c/.cpp 或 .h 文件中的以下指令将使您的应用程序尝试从程序集中加载 dll,而不仅仅是本地目录:
My first thought is, if you are statically linking a dll, it isnt a plugin. Just put the dll in the EXE folder and be done with it. That is the deployment configuration supported by windows for statically loaded DLLs.
That said, there are ways to achieve what you want. But they are mostly stupid, or complicated for no good reason: Your options are:
To turn a folder, with one or more dll's into an "assembly", simply add a file to the folder with the folders name.manifest.
So, plugins.manifest :-
It is a VERY good idea to ensure that the folder and the dll's name is different as if the dll name is the assembly name windows starts looking at its embedded manifest file for information about the assembly.
Assuming you are using Visual Studio 7 or later, the following directive added to a .c/.cpp or .h file in the project will then make your application attempt to load dlls from the assembly rather than just the local directory:
扩展并详细说明克里斯对“程序集”子目录的提议:
旁注:克里斯还有两篇关于更多详细信息的精彩文章:
回答一种从中央存储库加载 DLL 的方法
本文还解释了如何在应用程序配置文件中利用
探测 privatePath
将 DLL 放在子文件夹之外。MS docs
这实际上称为 “Private Assembly” 和 MS 文档是这样解释的:
您在程序文件夹
C:\Test\Program\app.exe
中找到了值得信赖的旧可执行文件,并且您想要 -- at Load-Time -- 从插件加载 DLL 文件
子文件夹,即C:\Test\Program\plugins\tool1.dll
不会弄乱PATH
或任何其他内容。您需要:
使用以下内容编译 app.exe:
注意:在我的测试系统上需要编译/链接它,而不是使用外部清单(
app.exe.manifest
),我没有找到还没有弄清楚为什么。 (*一)但是,也可以使用
mt
工具(而不是使用链接器编译指示)将下面列出的清单文件嵌入/合并到可执行文件中。 (配置 > 清单工具 > 其他清单文件
)将 tool1.dll 放入
plugins
子文件夹C:\Test\Program\plugins\plugins.manifest
,该文件如下所示:plugins.manifest:
就是这样。启动 app.exe 将在加载时自动在子文件夹中查找 dll。
(*a) :合并此清单文件有效,但您不能将其用作唯一的外部清单文件,我怀疑这是因为它缺少构建系统已放入可执行文件中的所有其他清单信息!
Expanding and detailing Chris' proposal of an "assembly" subdirectory:
Side note: Chris also has two excellent write ups of more details:
Answer to A way to load DLL from central repository
This on also explains how you can leverage
probing privatePath
in the application config files to put the DLLs outside of a subfolder.MS docs
This is actually called a "Private Assembly" and MS docs explain it this way:
The example
You got you're trusty old executable in you program folder
C:\Test\Program\app.exe
and you want to -- at Load-Time -- load your DLL file from thePlugins
subfolder, i.e.C:\Test\Program\plugins\tool1.dll
without messing withPATH
or any other stuff.You need to:
Compile app.exe with:
Note: Compiling/Linking this in, instead of using an external manifest (
app.exe.manifest
) is required on my test system, I didn't find out why yet. (*a)What also works however is embedding/merging the manifest file listed below into the executable with the
mt
tool, instead of with the linker pragma. (Configuration > Manifest Tool > Additional Manifest Files
)put tool1.dll intro the
plugins
subfolderC:\Test\Program\plugins\plugins.manifest
and that one looks like this:plugins.manifest:
That's it. Starting app.exe will automatically find the dll in the subfolder at Load-Time.
(*a) : Merging this manifest file works, but you can't use that as the sole external manifest file, and I suspect it's because it's missing all the other manifest info the build system already places into your executable!