gpt4 book ai didi

.net - 程序集加载版本不匹配 : Why is it loading?

转载 作者:行者123 更新时间:2023-12-04 20:54:39 24 4
gpt4 key购买 nike

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

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

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

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

根据 MSDN :

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.



问题:
  • 为什么它起作用了?
  • 如何使它不起作用?
  • 奖励问题:在构建过程中会发生什么?外部依赖的版本不是硬编码到主依赖的吗?

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

    这是 HelloWorld.exe 的 list :
    // Metadata version: v2.0.50727
    .assembly extern mscorlib
    {
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
    .ver 2:0:0:0
    }
    .assembly extern Hello
    {
    .ver 2:0:0:0
    }
    .assembly HelloWorld
    {
    ...//snipped
    }

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

    === 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:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.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:\Users\ian.uy\Desktop\HelloWorld\HelloWorld\bin\Debug\Hello.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:\Users\ian.uy\Desktop\HelloWorld\HelloWorld\bin\Debug\Hello.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)

    因此,答案如下:

    Why did it work?



    因为程序集不是强命名的

    How to make it NOT work?



    使程序集具有强名称

    What happens during the build process?



    依靠
  • Use specific version = false:根据项目中与引用匹配的第一个文件进行编译,采用任何版本
  • Use specific version = true:根据找到的第一个与包含项目中指定版本的引用匹配的文件进行编译

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



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

    关于.net - 程序集加载版本不匹配 : Why is it loading?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5883489/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com