話說ODP.NET在10.2版搞了一個飛機--Oracle.DataAccess.dll的版號原本已到了9.2.0.700,卻在ODP.NET 10.2時砍掉重練,重新從2.102.2.20編起,而依照.NET的版本法則,原本參照ODP.NET 9.2編譯的程式,在只有ODP.NET 10.2+的環境下,會因2.102小於9.2而被視為更舊的版本,無法改參照ODP.NET 10.2+而爆出以下的錯誤: (下例發生在安裝了ODP.NET 11.2的Windows 2008 R2 x64)

CS1705: Assembly 'MyWebControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'Oracle.DataAccess, Version=9.2.0.700, Culture=neutral, PublicKeyToken=89b483f429c47342' which has a higher version than referenced assembly 'Oracle.DataAccess, Version=2.112.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342'

原本這條限制可以靠在同機器安裝多個ODP.NET版本配合Assembly Redirect解決,但很不幸地,x64平台無法安裝ODP.NET 9207(登楞!!)。面對這段孽緣,之前的處理方法多半是默默地開一個x86 VM專門對付有歷史包袱綁死ODP.NET 9.2的專案,再不然就是偷偷把參照改成ODP.NET 10.2+自己弄個私房版本DLL在x64平台上使用,彙總到工作專案裡時繼續用吃9.2的公版DLL。總之,每回在x64上搞ODP.NET版本相容老是弄到一肚子火。(到底是哪個豬頭決定9.2的下一版要改成2.X的? 給我踹共!!)

今天又遇到同樣的問題,但剛好參照ODP.NET 9207的DLL沒有Source Code無法重新編譯,我又很鐵齒地不想開VM安裝VS2010,所以很邪惡地用類似駭客的手法解決問題:

  1. 開啟Visual Studio Command Prompt (2010)
  2. ildasm MyControl.dll /output:MyControl.il
  3. 使用文字編輯器開啟MyControl.il,找到以下這段Manifest
    .assembly extern System.Xml
    {
      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
      .ver 2:0:0:0
    }
    .assembly extern Oracle.DataAccess
    {
      .publickeytoken = (89 B4 83 F4 29 C4 73 42 )                         // ....).sB
      .ver 9:2:0:700
    }
    .assembly extern System
    {
      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
      .ver 2:0:0:0
    }
  4. 將以上橘色的.ver 9:2:0:700改成.ver 2:112:1:0,重新存檔
  5. ilasm MyControl /dll /output:MyControlRef11.dll

這樣子就可將Manifest中對ODP.NET的參照由9.2.0.7改成2.112.1.0,在沒有Source Code的情況下修改了ODP.NET的參照版本。將修改過的DLL放進專案,就能順利編譯囉! 算是另類的解法。


Comments

Be the first to post a comment

Post a comment