为什么私有程序集发现不使用完全限定的程序集名称来匹配,而是使用文件名?

发布于 2024-08-07 19:18:33 字数 1904 浏览 3 评论 0原文

我们的应用程序动态加载一组私有程序集,每个程序集都驻留在自己的子目录下。它们每个都有自己的依赖项,这些依赖项也位于同一子目录中。每个程序集都是强命名的,依赖项是相同的库,但版本不同。

MyApp
|-> Folder1\
|          |->PrivateAssembly1.dll
|          |->Dependency.dll                   Version 1.0.0.0
|
|-> Folder2\
|          |->PrivateAssembly2.dll
|          |->Dependency.dll                   Version 2.0.0.0
|
...

由于我们正在进行 xcopy 部署,因此我们不使用 GAC。

我们还将探测 privatePath 定义为“Folder1;Folder2”,以解决找不到私有程序集的任何问题。

问题是 PrivateAssembly1.dll 似乎找到了它的依赖项,但 PrivateAssembly2.dll 没有。或者更确切地说,它似乎试图使用Folder1中的Dependency.dll而不是Folder2。

我知道这些问题可以通过使用 AssemblyResolve 事件手动解决,但这不是最干净的方法。还有其他我忽略的解决方案吗?

感谢您的任何和所有想法。

更新:

融合日志工具的输出:

LOG: DisplayName = Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=#########
 (Fully-specified)
LOG: Appbase = file:///C:/Workspaces/Shell/MyApp/bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
...
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Dependency.DLL.
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Dependency/Dependency.DLL.
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Folder2/Dependency.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Workspaces\Shell\MyApp\bin\Folder2\Dependency.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Dependency, Version=2.0.0.0, Culture=neutral, PublicKeyToken=#######
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

所以基本上,它在Folder2中找到了一个Dependency.dll,尝试加载它却发现版本不匹配。我假设它接下来会尝试Folder1,但它就停在那里......

Our application dynamically loads a set of private assemblies that each reside under their own sub-directory. They each have their own dependencies which are also in that same sub-directory. Each assembly is strongly named and the dependencies are the same library, but different versions.

MyApp
|-> Folder1\
|          |->PrivateAssembly1.dll
|          |->Dependency.dll                   Version 1.0.0.0
|
|-> Folder2\
|          |->PrivateAssembly2.dll
|          |->Dependency.dll                   Version 2.0.0.0
|
...

Since we're doing xcopy deployment so we don't use the GAC.

We also have probing privatePath defined to "Folder1;Folder2" to solve any issue of not finding the private assemblies.

The problem is that PrivateAssembly1.dll seems to find its dependency, but PrivateAssembly2.dll does not. Or rather, it seems to be trying to use Dependency.dll from Folder1 in stead of Folder2.

I know these issues can be manually resolved by using the AssemblyResolve event, however this isn't the cleanest approach. Are there other solutions I am overlooking?

Thanks for any and all ideas.

Update:

The output of the Fusion Log tool:

LOG: DisplayName = Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=#########
 (Fully-specified)
LOG: Appbase = file:///C:/Workspaces/Shell/MyApp/bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
...
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Dependency.DLL.
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Dependency/Dependency.DLL.
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Folder2/Dependency.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Workspaces\Shell\MyApp\bin\Folder2\Dependency.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Dependency, Version=2.0.0.0, Culture=neutral, PublicKeyToken=#######
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

So basically, it finds a Dependency.dll in Folder2, attempts to Load it only to see that the version doesn't match. I would assume it would try Folder1 next, but it just stops there...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

东走西顾 2024-08-14 19:18:33

首先要做的是使用 Fusion 日志查看器“FUSLOGVW.exe1 启用程序集加载的日志记录。这将向您显示 CLR 尝试从何处加载依赖项。这应该确认某些位置丢失,并告诉您 .config 中缺少什么。

[编辑:现在带有日志]

一旦找到匹配的程序集名称,就不再进行(文件)搜索。即保持你的程序集名称唯一。

(这类似于 C++ 方法重载解析,首先找到最佳匹配,然后检查可访问性,因此不会考虑可访问的较弱参数匹配。)

1 注意。如果您在 64 位系统上运行,则该工具有单独的 32 位和 64 位版本:确保您使用正确的版本。

First thing to do is use the Fusion Log Viewer "FUSLOGVW.exe"1 to enable logging of assembly loading. This will show you where the CLR is trying to load the dependencies from. This should confirm some location is missing—and tell you what you are missing in your .config.

[Edit: Now with log]

Once a matching assembly name has been found, no more (file) search takes place. I.e. keep your assembly names unique.

(This is similar to C++ method overload resolution, first the best match is found and then accessibility is checked, so a weaker parameter match that is accessible will not be considered.)

1 NB. If you are running on a 64bit system, thee are separate 32 and 64bit versions of this tool: ensure you use the right one.

花落人断肠 2024-08-14 19:18:33

.NET 反对这一点的原因是您试图将同一程序集的不同版本加载到应用程序域中。您必须决定是否可以让 PrivateAssembly1.dll 和 PrivateAssembly2.dll 实际上使用相同的库版本。如果可能的话,这将为您省去很多麻烦。

确实可以通过添加加载 Dependency.dll 的自定义解析器来强制将 Dependency.dll 的两个版本加载到您的应用程序域中,但请注意,如果您这样做,您将进入一个相当狭窄的路径。例如,两个版本中的任何静态变量都会有不同版本,并且在Folder1\Dependency.dll程序集中创建的类型将不会被Folder2\Dependency.dll程序集识别,反之亦然,即使这些类型可能看起来“相同”。

The reason why .NET objects to this is that you are trying to load different versions of the same assembly into the appdomain. You have to decide if you can let PrivateAssembly1.dll and PrivateAssembly2.dll actually use the same library version. This will save you quite a lot of trouble if it is possible.

It is indeed possible to force both versions of Dependency.dll to load into your appdomain by adding a custom resolver that loads it, but be aware that you are entering a rather narrow path if you do this. For instance, there will be different versions of any static variables in both versions, and also the types created in the Folder1\Dependency.dll assembly will not be recognized by the Folder2\Dependency.dll assembly, and vice versa, even though the types might seem to be "the same".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文