System.BadImageFormatException: 未能載入檔案或組件 "XXX" 或其某一個相依項。嘗試載入格式不正確的程式。
此錯誤核心原因:**位元數不匹配**——64 位元進程嘗試載入 32 位元組件,或反之。
x86 或 Any CPU (Prefer 32-bit),但 IIS 以 64 位元執行iisreset原理:強制 w3wp.exe 以 32 位元 (WoW64) 執行,可載入 32 位元相依組件。
效果:編譯輸出強制 32 位元 PE 格式,即使 IIS 為 64 位元也會在 WoW64 下執行。
適用場景:純 .NET 專案、或所有第三方庫已支援 64 位元 (如 Oracle.ManagedDataAccess、Microsoft.Data.SqlClient 等)。
註冊表路徑: HKLM\Software\Microsoft\Fusion
新增 DWORD: EnableLog = 1
新增 DWORD: LogFailures = 1
新增 DWORD: LogResourceBinds = 1
新增 String: LogPath = C:\FusionLogs\ (需預先建立資料夾,且 IIS_IUSRS 有寫入權限)
重現錯誤後,查看 C:\FusionLogs\ 下的 HTML 記錄,即可看到確切失敗的組件名稱、版本、公開金鑰、搜尋路徑。
Developer Command Prompt:
corflags YourAssembly.dll
輸出範例:
Version : v4.0.30319
CLR Header: 2.5
PE : PE32
CorFlags : 0x3
ILONLY : 1
32BITREQ : 1 <-- 此為 1 表示強制 32 位元
32BITPREF : 0
Signed : 0
PE32 + 32BITREQ=1 = 僅 32 位元PE32 + 32BITPREF=1 = Any CPU Prefer 32-bitPE32+ = 64 位元Sysinternals Process Explorer → View → Select Columns → Process Image → 勾選 Platform。觀察 IIS 工作進程顯示 32-bit 或 64-bit。
| 組件/套件 | 32 位元解決 | 64 位元替代方案 |
|---|---|---|
| Oracle Client (System.Data.OracleClient) | 啟用 32 位元集區 | 改用 Oracle.ManagedDataAccess (純 .NET, Any CPU) |
| Microsoft Jet/ACE OLEDB (Access/Excel) | 啟用 32 位元集區 | 無 64 位元 Jet,改用 ACE 64 位元驅動程式 |
| Crystal Reports 13/14 | 啟用 32 位元集區 | CR for VS 2017+ 支援 64 位元 |
| C++ CLI 混合模式組件 | 編譯為 x86 | 提供 x64 版本原生 DLL |
| COM 元件 (Interop) | 啟用 32 位元集區 | 需 64 位元 COM Server |