Oracle Client 版本問題像鬼魂般揮之不去,x86/x64、11.2/12.1...,歷經多年糾纏,現在遇到 .NET 要連 Oracle,我一律力推改用 Managed ODP.NET

但老系統多如牛毛,老鳥都知道「If it works, don't touch it!」是有益身心健康的鐵律,遇到作業系統升級、擴充整併,面對還在用 Unamanged ODP.NET 11.x/12.x 的國寶古蹟,咱們還是得小心翼翼,好好安裝設妥 Oracle Client,確保它能再戰十年。(有時真希望它自燃算了,但我相信一旦發生,維運人員通常會被綁在上面一起燒)

最近遇到搬系統的需求,那堆老問題一一現身跟我打招呼,一個都沒缺席:An attempt was made to load a program with an incorrect format.The provider is not compatible with the version of Oracle clientUnable to find the requested .NET Framework Data Provider. It may not be installed....

靠著過往的經驗跟 KB,問題一一解決,但讓我覺得是該整理一份安裝 Oracle Client 的 SOP,一次做對讓版本相關問題減到最少。

先說概念,同一台機器可以安裝多個版本 Oracle Client,11.2/12.1/12.2/19,每個版本又可區分 32 或 64 位元版。Unmanaged ODP.NET (Oracle.DataAccess.dll) 需依賴對映的版本運作(版號、32/64 都要相符),容易衍生一堆版本問題。

GAC 與發行者原則是解決 Oracle 版本的利器。原理是將最新版 Oracle.DataAccess.dll 註冊到 GAC,並設定發行者原則將舊版導向到最新版,如此可強制整台機器使用該版本 ODP.NET,不需個別在 web.config 加入 bindingRedirect 設定,甚至可將 /bin/Oracle.DataAccess.dll 刪除減少混淆。對以上運作原理不熟的同學可參考舊文:

由於 Oracle Client 安裝完並不會自動將 ODP.NET 註冊到 GAC (註:ODAC 12.2 版起不再自動註冊 GAC),也不會註冊發行者原則,要借用這個方便機制得手工完成。之前註冊 GAC 及發行者原則我都是去有裝 .NET Framework SDK 借用 gacutil.exe 進行操作,這回發現原來 Oralce 有自帶工具 oraprovcfg.exe,其位於 %ORACLE_CLIENT_HOME%\ODP.NET\bin\4 目錄下 (.NET 2.x 版本也有),故在裝好 Oracle Client 後,參考官方文件應再完成以下操作:

# 設定 ORACLE_CLIENT_HOME 環境變數並切換到 %ORACLE_CLIENT_HOME%\odp.net\bin\4
set ORACLE_CLIENT_HOME=D:\oracle\product\19c\client32
cd /d %ORACLE_CLIENT_HOME%\odp.net\bin\4
# 在 machine.config 加入 DbProvider 設定,解決 Unable to find the requested .NET Framework Data Provider.
OraProvCfg.exe /action:config  /force /product:odp /frameworkversion:v4.0.30319 /providerpath:%ORACLE_CLIENT_HOME%\odp.net\bin\4\Oracle.DataAccess.dll
# 將 ODP.NET 註冊到 GAC
OraProvCfg.exe /action:gac /providerpath:%ORACLE_CLIENT_HOME%\odp.net\bin\4\Oracle.DataAccess.dll
# 將 11.2 導向最新版
OraProvCfg.exe /action:gac /providerpath:%ORACLE_CLIENT_HOME%\odp.net\PublisherPolicy\4\Policy.4.112.Oracle.DataAccess.dll
# 將 12.1 導向最新版
OraProvCfg.exe /action:gac /providerpath:%ORACLE_CLIENT_HOME%\odp.net\PublisherPolicy\4\Policy.4.121.Oracle.DataAccess.dll
# 將 12.2 導向最新版 (若安裝的是 19c 版)
OraProvCfg.exe /action:gac /providerpath:%ORACLE_CLIENT_HOME%\odp.net\PublisherPolicy\4\Policy.4.122.Oracle.DataAccess.dll

如此,該主機用到 ODP.NET 的程式將無視原本的版本依賴,改用註冊到 GAC 的最新版,從此避開惱人的版本相同問題,水啦。(註:32/64 位元還是得分清楚)

Tips of registering ODP.NET to GAC and using publisher policy to avoid version compatability issue.


Comments

# by UG

黑大您好, 想問一下文中有提到"由於 Oracle Client 安裝完並不會自動將 ODP.NET 註冊到 GAC,也不會註冊發行者原則,要借用這個方便機制得手工完成。" 但與 https://blog.darkthread.net/blog/aspnet-bin-dll-loading/ 一文中提及的結論"安裝 Oracle Client 時會一併安裝 ODP.NET 到 GAC,故實務上 ASP.NET 會使用裝在 GAC 的組件,並不需要部署 /bin/Oracle.DataAccess.dll。" 是否有衝突? 謝謝。

# by Jeffrey

to UG,謝謝提醒,我完全忘記以前會自動註冊了,調查結果在此 https://blog.darkthread.net/blog/gac-regiteration-in-odac-setup/

# by UG

謝謝黑大補充!!

Post a comment