dotnet pack 打包文件版本号引起 Could not load file or assembly 问题
如果不是遇到,真的不會想到,代碼世界的問題真是千奇百怪,這次遇到的是?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 Releasedotnet 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 沒問題,運行時卻報下面的錯誤,整個應用都無法啟動。
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 文件的信息時發現了線索:
?
不對,文件版本號怎么是 1.0 ,打的明明是 2.2 的包?
Review 打包腳本后恍然大悟
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 文件版本就與包的版本就一致了
在項目中升級到這個包,問題也就解決了。
原來,.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 才行,原來也是文件版本號的問題,只要修改一下文件版本號就能解決。
另外,程序集的依賴信息保存在?.deps.json 文件中,如果不能修改程序集文件的版本號,應該可以通過修改?.deps.json 文件中 runtime 配置的?fileVersion 值來實現。
"runtime": {"lib/netstandard2.0/EnyimMemcachedCore.dll": {
"assemblyVersion": "2.2.2.0",
"fileVersion": "2.2.2.0"
}
}
原文地址:https://www.cnblogs.com/dudu/p/10880845.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?
總結
以上是生活随笔為你收集整理的dotnet pack 打包文件版本号引起 Could not load file or assembly 问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跟我学: 使用 fireasy 搭建 a
- 下一篇: ASP.NET Core MVC 视图