dotnet pack 打包文件版本号引起 "Could not load file or assembly" 问题

栏目: ASP.NET · 发布时间: 5年前

内容简介:如果不是遇到,真的不会想到,代码世界的问题真是千奇百怪,这次遇到的是 dotnet pack 打包文件版本号引起的问题。之前进行 nuget 打包都是在 Visual Studio build 时进行,版本号时通过 .csproj 中的 VersionPrefix 指定,没遇到问题。最近,改为通过 shell 脚本在 linux 上打包,开始的 shell 脚本是怎么写的:

如果不是遇到,真的不会想到,代码世界的问题真是千奇百怪,这次遇到的是 dotnet pack 打包文件版本号引起的问题。

之前进行 nuget 打包都是在 Visual Studio build 时进行,版本号时通过 .csproj 中的 VersionPrefix 指定,没遇到问题。

最近,改为通过 shell 脚本在 linux 上打包,开始的 shell 脚本是怎么写的:

dotnet pack -c Release /p:version=$(git tag --sort=committerdate | tail -1 )

后来发现 dotnet pack 不能自动 build 项目,这个问题不是从哪个版本的 .net core cli 开始出现的。

为了解决这个问题,在 dotnet pack 命令之前添加了 dotnet build 命令:

dotnet build -c Release
dotnet pack -c Release /p:version=$(git tag --sort=committerdate | tail -1 ) 

采用这个脚本发包后,最近几次发包遇到了奇怪的问题,比如发布了 EnyimMemcached 2.2 包,在引起该包的 A 项目中升级到 EnyimMemcached 2.2,而 A 项目所引用的其他 nuget 包也引用了 EnyimMemcached 但引用的是旧版 EnyimMemcached 2.1.12 ,build 没问题,运行时却报下面的错误,整个应用都无法启动。

System.IO.FileLoadException: Could not load file or assembly 'EnyimMemcachedCore, Version=2.1.12.0, Culture=neutral, PublicKeyToken=null'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'EnyimMemcachedCore, Version=2.1.12.0, Culture=neutral, PublicKeyToken=null'
   at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)

对于这样的依赖同一个包的不同版本问题,.net core 中已经进行了有效解决,如果存在版本冲突,在 build 时就能发现,比如 解决 .net core 中 nuget 包版本冲突问题 ,只要 build 通过,基本不会出现上面的问题,.net core runtime 会自动使用最高版本。

而我们现在却遇到了这个 .net core 已经解决的问题,让人莫名其妙,无从下手。今天再次遇到这个问题时,想到把包解开看看其中有没有与运行时相关的元数据信息。

解开一看,除了 dll 文件,没有其他用于运行时的文件,在查看这个 dll 文件的信息时发现了线索:

dotnet pack 打包文件版本号引起

不对,文件版本号怎么是 1.0 ,打的明明是 2.2 的包?

Review 打包脚本后恍然大悟

dotnet build -c Release

dll 文件是在 build 时生成的,Build 时没有添加版本信息,于是使用了默认版本号1.0。

赶紧改进脚本试试

VERSION=$(git tag --sort=committerdate | tail -1)
dotnet build /p:version=$VERSION -c Release Enyim.Caching
dotnet pack -c Release /p:version=$VERSION Enyim.Caching

这样改进后,打出的包中的 dll 文件版本就与包的版本就一致了

dotnet pack 打包文件版本号引起

在项目中升级到这个包,问题也就解决了。

原来,.net core 在 build 时只检查 nuget 包的版本号,不检查包中 dll 程序集文件的版本号,而 .net core runtime 在运行时会检查程序集文件的版本号。而我们遇到的问题就是由于 build 时与运行时的检查机制不一致,造成错误的文件版本号没有在 build 时被检查出来,从而在应用运行的时候才发现,大大增加了问题的排查难度。

为什么一定要在运行时检查程序集文件的版本号而且在版本号出现问题时让整个应用都无法启动?反正就这一个文件,写个告警日志,继续用这个文件就是了,如果无法使用这个文件,再让整个应用挂掉也不迟,这个地方有点想不通。

今天的发现也让之前的另外一个疑问有了答案,之前在 .NET Core 2.2 中遇到了 System.Data.SqlClient 的问题,想看看最新版的 corefx 是否解决了这个问题,于是签出最新版的 corefx 代码 build 出了 System.Data.SqlClient.dll 替换 .NET Core 2.2 中的同名文件,运行时也总是报错 "Could not load file or assembly" ,只有签出 release/2.2 分支的代码 build 才行,原来也是文件版本号的问题,只要修改一下文件版本号就能解决。


以上所述就是小编给大家介绍的《dotnet pack 打包文件版本号引起 "Could not load file or assembly" 问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Linux内核设计与实现

Linux内核设计与实现

拉芙 / 陈莉君、唐华、张波 / 机械工业出版社 / 2006-1 / 38.00元

《Linux内核设计与实现》基于Linux2.6内核系列详细介绍Linux内核系统,覆盖了从核心内核系统的应用到内核设计与实现等各方面的内容。主要内容包括:进程管理、系统调用、中断和中断处理程序、内核同步、时间管理、内存管理、地址空间、调试技术等。本书理论联系实践,既介绍理论也讨论具体应用,能够带领读者快速走进Linux内核世界,真正开发内核代码。 本书适合作为高等院校操作系统课程的教材......一起来看看 《Linux内核设计与实现》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具