程序集加载版本不匹配:为什么加载? [英] Assembly Loading Version Mismatch: Why is it loading?

查看:24
本文介绍了程序集加载版本不匹配:为什么加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个程序集:HelloWorld.exe 和 Hello.dll.exe是主程序集,dll正在被主程序集使用.

I have two assemblies: HelloWorld.exe and Hello.dll. The exe is the main assembly and the dll is being used by the main assembly.

我编译了 HelloWorld.exe (1.0.0) 和 Hello.dll (1.0.0).我将程序集放在不同的文件夹中.

I compiled both HelloWorld.exe (1.0.0) and Hello.dll (1.0.0). I placed the assemblies on a different folder.

然后我将 Hello.dll 的版本更改为 2.0.0,并继续用 2.0.0 版本覆盖 Hello.dll 1.0.0.然后我启动了 HelloWorld.exe,它运行良好.

I then changed the version of Hello.dll to 2.0.0 and proceeded to overwrite the Hello.dll 1.0.0 with the 2.0.0 version. I then launch HelloWorld.exe and it worked fine.

我预计它会立即崩溃并烧毁,因为我编译 EXE 时引用的 Hello.dll 是 1.0.0.现在,1.0.0 DLL 已被 2.0.0 取代,但它仍然有效!

I expected it to crash and burn immediately because the referenced Hello.dll when I compiled the EXE was 1.0.0. Now, the 1.0.0 DLL has been replaced by 2.0.0 but it still worked!

根据 MSDN:

默认情况下,程序集将只使用完全相同的类型构建和测试的程序集(名称和版本号).也就是说,如果您的程序集使用版本 1.0.0.2 中的类型另一个程序集,它将(默认情况下)不使用相同的类型另一个程序集的 1.0.0.4 版.这种使用名称和识别引用程序集的版本有助于避免DLL 地狱"升级到一个应用程序会破坏其他应用程序的问题.

By default, an assembly will only use types from the exact same assembly (name and version number) that it was built and tested with. That is, if you have an assembly that uses a type from version 1.0.0.2 of another assembly, it will (by default) not use the same type from version 1.0.0.4 of the other assembly. This use of both name and version to identify referenced assemblies helps avoid the "DLL Hell" problem of upgrades to one application breaking other applications.

问题:

  1. 为什么有效?
  2. 如何让它不起作用?
  3. 额外问题:构建过程中会发生什么?外部依赖的版本不是硬编码到主依赖中吗?

请注意,Hello.dll 不是强命名的.

这是 HelloWorld.exe 的清单:

Here's the manifest for HelloWorld.exe:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .zV.4..
  .ver 2:0:0:0
}
.assembly extern Hello
{
  .ver 2:0:0:0
}
.assembly HelloWorld
{
...//snipped
}

这是从 Fuslogvw.exe(程序集绑定日志查看器)中获取的程序集绑定日志:

Here's the Assembly Binding Log taken from Fuslogvw.exe (Assembly Binding Log Viewer):

=== Pre-bind state information ===
LOG: User = ian.uy
LOG: DisplayName = Hello, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Users/ian.uy/Desktop/HelloWorld/HelloWorld/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:WindowsMicrosoft.NETFrameworkv2.0.50727configmachine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/ian.uy/Desktop/HelloWorld/HelloWorld/bin/Debug/Hello.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:Usersian.uyDesktopHelloWorldHelloWorldinDebugHello.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Hello, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
LOG: Binding succeeds. Returns assembly from C:Usersian.uyDesktopHelloWorldHelloWorldinDebugHello.dll.
LOG: Assembly is loaded in default load context.

推荐答案

运行时出于版本控制的目的区分常规程序集和强命名程序集.版本检查只发生在强名称程序集上.

The runtime distinguishes between regular and strong-named assemblies for the purposes of versioning. Version checking only occurs with strong-named assemblies.

(来源:https://docs.microsoft.com/en-us/dotnet/framework/app-domains/assembly-versioning)

因此,答案如下:

为什么有效?

因为程序集不是强命名的

Because the assembly isn't strong-named

如何让它不工作?

使程序集具有强名称

在构建过程中会发生什么?

What happens during the build process?

视情况而定

  • 使用特定版本 = false:针对项目中与引用匹配的第一个文件进行编译,采用任何版本
  • 使用特定版本 = true:针对找到的第一个与引用匹配的文件进行编译,包括项目中的指定版本
  • Use specific version = false: compiles against the first file matching the reference in the project, takes any version
  • Use specific version = true: compiles against the first file found matching the reference including the specified version in the project

外部依赖的版本不是硬编码到主依赖中吗?

Isn't the version of external dependencies hard coded to the main dependency?

是的,引用程序集的版本是硬编码的.您可以通过使用反编译器(例如 ILSpy)读取此信息来验证这一点

Yes, the versions of referenced assemblies are hard-coded. You can verify this by using a decompiler (e.g. ILSpy) to read this information

这篇关于程序集加载版本不匹配:为什么加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆