與 Unmanged ODP.NET 纏鬥多年,自以為看遍各種球路,今天再遇上沒見過的變種新球路 - 四縫線變速深卡球,經驗值再加一。

同事將程式部署到測試環境,網站所引用的程式庫參照了 ODP.NET 版,噴出Unable to load DLL 'OraOps12.dll': Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) 錯誤。

據了解,該主機近期並沒有安裝或異動 Oracle Client,我用 ASP.NET /bin 組件載入跟你想的不一樣 提到的 ChkOdpNetVersion.aspx Inline ASPX 技巧,先確程式當下使用的是 GAC 4.121.2.0 版。之前遇過 11.2/12.1 Oracle Client 並存時 PATH 環境變數路徑順序造成問題,當時是爆在 OraOps12.dll,但錯誤訊息是The specified procedure could not be found. (Exception from HRESULT: 0x8007007E),這回則是Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)),檢查過 product\12.1.0\client\bin\OraOps12.dll 確定有 Everyone 讀取權限,似乎又不是權限問題,這又是哪招?

沒辦法,拔出久未出鞘的 Process Monitor 寶劍。登楞! 是權限問題沒錯,但爆在 oci.dll:

檢查 oci.dll,果然沒開讀取權限,加上 Everyone 讀取後原錯誤消失,但執行 Oracle 查詢的 .NET 函式冒出另外一個錯誤:Object reference not set to an instance of an object. 心想 Oracle 問題已解,便朝商業邏輯方面追查,追查一陣子,種種假設被一一排除,將箭頭再指回 Oracle Client,再開一次 Process Monitor,這才發現還是權限問題,但這回換另一個檔案 oraciei12.dll,噴出的訊息不含 0x800X0005 Access Denied 提示,而是物件未設定的模糊訊息:

為防範未爆彈,對整個 12.1.0\client 目錄套用 Everyone 讀取,問題終告排除。

【今日心得】

  • 如果有的選,請指明 Managed ODP.NET 免受鳥氣。(拎杯受夠 ODP.NET 與各版本 Oracle Client 的無止盡糾葛惹)
  • ODP.NET 噴出 0x80070005、0x80040005 時,請優先檢查 Oracle Client 相關 dll 檔案,client 目錄與 bin 目錄都有嫌疑,最好全部重設。而權限問題也可能以 Object reference not set to an instance of an object. 方式呈現。
  • 就算沒有安裝或異動 Oracle Client,Oracle dll 檔案有時仍有可能因不明原因權限改變導致存取被拒。
  • 找檔案 Access Denied 問題,Process Monitor 是絕佳神器,能少繞遠路節省除錯時間。
  • 異動 Oracle Client 後記得 IISRESET,必要時重開機。

Experience of troubleshooting ODP.NET 0x80070005 error.


Comments

Be the first to post a comment

Post a comment


49 + 8 =