文章目錄
System.IO.FileLoadException : Could not load file or assembly
前情提要:公司有個專案需要與外部 partner 週期性進行資料交換,是常見的排程作業但 partner 沒有提供測試環境,加上 partner 的 api 環境有鎖定來源 ip,也就是所有的功能開發都需要憑空想像或是透過 production 來 debug XD 雖然不是第一次遇到這種需求,但還是覺得無力感很重呀
不過就是因為這個專案的特殊性才讓我遇到 System.IO.FileLoadException : Could not load file or assembly
問題,當下我花了一陣子才想到原因加上違反正常 CI/CD 流程,特別筆記一下加深印象
錯誤訊息
訊息內容
c:\>AD3ToMongoDB.exe install Topshelf.HostFactory Error: 0 : An exception occurred creating the host, System.IO.FileLoadException: Could not load file or assembly 'Topshelf, Version=3.2.150.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: 'Topshelf, Version=3.2.150.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b' at AD3ToMongoDB.Program.<>c.<Main>b__0_1(ServiceConfigurator`1 s) at Topshelf.ServiceExtensions.CreateServiceBuilderFactory[TService](Action`1 callback) at Topshelf.ServiceExtensions.Service[TService](HostConfigurator configurator, Action`1 callback) at AD3ToMongoDB.Program.<>c.<Main>b__0_0(HostConfigurator x) in C:\Users\yowko.tsai\source\repos\AD3ToMongoDB\Program.cs:line 19 at Topshelf.HostFactory.New(Action`1 configureCallback) WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog]. Topshelf.HostFactory Error: 0 : The service terminated abnormally, System.IO.FileLoadException: Could not load file or assembly 'Topshelf, Version=3.2.150.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: 'Topshelf, Version=3.2.150.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b' at AD3ToMongoDB.Program.<>c.<Main>b__0_1(ServiceConfigurator`1 s) at Topshelf.ServiceExtensions.CreateServiceBuilderFactory[TService](Action`1 callback) at Topshelf.ServiceExtensions.Service[TService](HostConfigurator configurator, Action`1 callback) at AD3ToMongoDB.Program.<>c.<Main>b__0_0(HostConfigurator x) in C:\Users\yowko.tsai\source\repos\AD3ToMongoDB\Program.cs:line 19 at Topshelf.HostFactory.New(Action`1 configureCallback) at Topshelf.HostFactory.Run(Action`1 configureCallback) WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
錯誤截圖
問題釐清
確認正確引用
Topshelf
dll檢查是否複製 dll 至最終 output 資料夾
確認 Topshelf.HostFactory 使用的
Topshelf
dll 版本確認
Topshelf
dll 版本
解決方式
加入
Topshelf
的 bindingRedirect基本設定範例
<dependentAssembly> <assemblyIdentity name="Topshelf" publicKeyToken="b800c4cfcdeea87b" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly>
完整階層範例
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Topshelf" publicKeyToken="b800c4cfcdeea87b" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <configuration> <configSections>
心得
這是我第一次手動為 Topshelf 加上 bindingRedirect,過去雖然也常發生 dll 相依設定與實際版本不一致的狀況,但大多在進行 NuGet 套件安裝時就會自動加上 bindingRedirect,記起這件事立馬重新檢視 config 設定也才發現原來確實已自動加上,而這就是違反一般正常 CI/CS 流程所造成的主要問題:因為專案是直接透過 production 開發,在功能確認完成前並未加入標準 CI/CD 的設定中,造成直接部署時沒留意到 config 的變更而讓 bindingRedirect 的相關設定未被加入
雖然這次遇到的狀況是來自於需要配合 partner 的特殊性,不過追根究柢還是因為沒有預先建立 CI/CD 設定而造成的,再次親身體驗 CI/CD 標準化的重要性呀
參考資訊
文章作者 Yowko Tsai
上次更新 2021-10-15
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。