私有程序集和传递 DLL 依赖项?
Private Assembly and transitive DLL dependencies?
好的,所以我已经成功地设置了我的 Private Assembly for my plugins of my executable, like described here:(这只是一个例子,我的用例在技术上是相同的,但不是这样的插件。)
- 可执行文件使用应用程序清单在
plugins
程序集 上声明 dependentAssembly
plugins
子目录包含 plugins.manifest
plugins.manifest
声明 assemblyIdentity
,files
列出插件 DLL(例如,easyplug1.dll
和 xplug2.dll
)
我不太明白,也还没有找到任何直接解释的是,Private Assembly中的DLLs依赖的DLLs呢在?它们应该位于何处,如何找到?
示例:xplug2.dll
,是第 3 方本身 需要第 3 方 dll xbase.dll
。自然,xbase.dll 也简单地部署在插件目录中。这够了吗? 私有程序集是否需要列出仅由声明其依赖于 plugins
程序集的(可执行)模块传递使用的 DLL?
到目前为止的部分答案通过反复试验:
(A) 似乎 所有 DLL,以及那些仅从其他 "plugin" DLL 中使用的 DLL 必须列在私有程序集清单中——即本质上应该列出所有个DLL文件在plugins
程序集目录中。
(A.1) 任何未列出的 DLL 都不会在目录中找到,即使它是从同一子目录中的 DLL 引用的。
(A.2) 我假设 这是由于所有 DLL 加载机制使用可执行文件中的(仅)自定义 Activation Context,如果那里没有找到DLL,似乎是从可执行目录中搜索。
(A.3) 我试着用 the latest version of Dependency Walker (2.2.10011), but it seems it can't handle this transitive scenario at all: Primary dependencies are are shown correctly, but transitive secondary dependencies are not resolved from the manifest, but relative to the base directory. (Seems it follows plain LoadLibrary
semantics for the transient ones.)
查看依赖链
文件布局:
...\base\app.exe
// - contains Application Manifest declaring dependency on `plugins`
// - Loads xplug2.dll
...\base\plugins\xplug2.dll
// - Loads xbase.dll (which is only used by xplug2.dll internally)
...\base\plugins\xbase.dll
...\base\plugins\plugins.manifest
// - lists xplug2.dll (for sure)
// - *seems* to need to list also xbase.dll
简单的答案是,任何 "raw" 不属于程序集的 dll 将使用应用程序激活上下文 and/or 默认 dll 搜索规则进行搜索。并且 dll 搜索路径包括应用程序文件夹,但不包括在其中找到 dll 的任何文件夹(即,一个 dll 永远不会期望加载另一个偶然在同一文件夹中的 dll)。
因此,例如,如果您的程序集中的一个 dll 需要 openssl.dll,那么它将首先在 application.exe 的文件夹中搜索,而不是您的私人程序集文件夹,除非您特别明确地,将 openssl 添加到您的私人程序集。
答案是将 openssl.dll 显式添加到私有程序集(如果不同的 dll - 在不同的程序集中 - 需要不同版本的 openssl.dll,这顺便有助于保护应用程序的完整性)
在您的情况下,您可以有两个不同的私有程序集,每个都使用私有版本的 xbase.dll - 其中两个不同的 xbase.dll 可能非常不兼容。
好的,所以我已经成功地设置了我的 Private Assembly for my plugins of my executable, like described here:(这只是一个例子,我的用例在技术上是相同的,但不是这样的插件。)
- 可执行文件使用应用程序清单在
plugins
程序集 上声明 plugins
子目录包含plugins.manifest
plugins.manifest
声明assemblyIdentity
,files
列出插件 DLL(例如,easyplug1.dll
和xplug2.dll
)
dependentAssembly
我不太明白,也还没有找到任何直接解释的是,Private Assembly中的DLLs依赖的DLLs呢在?它们应该位于何处,如何找到?
示例:xplug2.dll
,是第 3 方本身 需要第 3 方 dll xbase.dll
。自然,xbase.dll 也简单地部署在插件目录中。这够了吗? 私有程序集是否需要列出仅由声明其依赖于 plugins
程序集的(可执行)模块传递使用的 DLL?
到目前为止的部分答案通过反复试验:
(A) 似乎 所有 DLL,以及那些仅从其他 "plugin" DLL 中使用的 DLL 必须列在私有程序集清单中——即本质上应该列出所有个DLL文件在plugins
程序集目录中。
(A.1) 任何未列出的 DLL 都不会在目录中找到,即使它是从同一子目录中的 DLL 引用的。
(A.2) 我假设 这是由于所有 DLL 加载机制使用可执行文件中的(仅)自定义 Activation Context,如果那里没有找到DLL,似乎是从可执行目录中搜索。
(A.3) 我试着用 the latest version of Dependency Walker (2.2.10011), but it seems it can't handle this transitive scenario at all: Primary dependencies are are shown correctly, but transitive secondary dependencies are not resolved from the manifest, but relative to the base directory. (Seems it follows plain LoadLibrary
semantics for the transient ones.)
文件布局:
...\base\app.exe
// - contains Application Manifest declaring dependency on `plugins`
// - Loads xplug2.dll
...\base\plugins\xplug2.dll
// - Loads xbase.dll (which is only used by xplug2.dll internally)
...\base\plugins\xbase.dll
...\base\plugins\plugins.manifest
// - lists xplug2.dll (for sure)
// - *seems* to need to list also xbase.dll
简单的答案是,任何 "raw" 不属于程序集的 dll 将使用应用程序激活上下文 and/or 默认 dll 搜索规则进行搜索。并且 dll 搜索路径包括应用程序文件夹,但不包括在其中找到 dll 的任何文件夹(即,一个 dll 永远不会期望加载另一个偶然在同一文件夹中的 dll)。
因此,例如,如果您的程序集中的一个 dll 需要 openssl.dll,那么它将首先在 application.exe 的文件夹中搜索,而不是您的私人程序集文件夹,除非您特别明确地,将 openssl 添加到您的私人程序集。
答案是将 openssl.dll 显式添加到私有程序集(如果不同的 dll - 在不同的程序集中 - 需要不同版本的 openssl.dll,这顺便有助于保护应用程序的完整性)
在您的情况下,您可以有两个不同的私有程序集,每个都使用私有版本的 xbase.dll - 其中两个不同的 xbase.dll 可能非常不兼容。