【古蹟維修日記】BindingRedirect 版號該填多少
| | | 1 | |
今天處理了一個 DLL 升級部署問題。
有個專案配合某 NuGet 程式庫的需求,System.Memory 由 4.5.3 升級到 4.5.5,部署時自然就一併更新了 System.Memory.dll。不料這引發了 SQLite 程式報錯:
[FileLoadException: 無法載入檔案或組件 'System.Memory, Version=4.0.1.1,
Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' 或其相依性的其中之一。
找到的組件資訊清單定義與組件參考不符。 (發生例外狀況於 HRESULT: 0x80131040)]
SQLitePCL.Batteries_V2.DoDynamic_cdecl(String name, Int32 flags) +0
SQLite.SQLiteConnection..cctor() +96
身為老司機,一看訊息就知怎麼一回事:SQLitePCL 需要 4.0.1.1 版的 System.Memory,而專案的 System.Memory 升級到新版,版本不符無法使用。
解法很簡單,在 .config 加上 bindingRedirect 設定,將 4.0.1.1 版導向新版即可。但問題來了,a.b.c.d 要填什麼?
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51"/>
<bindingRedirect oldVersion="0.0.0.0-a.b.c.d" newVersion="a.b.c.d"/>
</dependentAssembly>
填 4.5.5.0?

還是填 4.6.31308.1?

答案都不是,4.5.5 是 NuGet 的版號,4.6.31308.1 是 DLL 的 FileVersion,而組件的真正版號是 4.0.1.2!
可用 Visual Studio 查詢:

或用 PowerShell 讀取:

老實說,這問題十年前踩過,不過腦袋記不住這麼久的東西,就再留一篇筆記當作復習吧。
Describes a DLL version conflict in deployment and explains how to resolve it using bindingRedirect with the correct assembly version.
Comments
# by SY
為了這個問題,我弄了一個工具在程式執行前讀取同資料夾所有的版本與,然後將 0.0.0.0-999.999.999.999 全部填到 app.config 裡面,反正大部分都是兼容舊版本的對吧(?) 這真的是 net framework 時期的一個大坑.....