[茶包]Windows 7 SP1 導致含有 ADO 的程式失效問題

  • 23931
  • 0
  • ADO
  • 2012-10-03

有天,小喵更改一個以前同事所撰寫的舊元件,裡面的問題很簡單,就是SQL語法中少了一個欄位,把欄位加上去,很容易就可以將這個問題結案。可是,事情往往都不是心裡想的那麼單純。想不到加了一個欄位後,元件上線後竟然導致整個系統當掉。當時小喵的電腦已經升級到 Windows 7 SP1 。後來追查原因,竟然是因為【Windows 7 SP1修改了ADODB的IID碼】

緣起

有天,小喵更改一個以前同事所撰寫的舊元件,裡面的問題很簡單,就是SQL語法中少了一個欄位,把欄位加上去,很容易就可以將這個問題結案。可是,事情往往都不是心裡想的那麼單純。想不到加了一個欄位後,元件上線後竟然導致整個系統當掉。當時小喵的電腦已經升級到 Windows 7 SP1 。後來追查原因,竟然是因為【Windows 7 SP1修改了ADODB的IID碼】

Windows 7 SP1修改了ADODB的IID碼

當案發之後,小喵幾乎毫無頭緒,只不過是加了個SELECT的欄位,竟然會導致元件失效,甚至進而導致整個系統運作失效。經過回想最近的更新狀況,並且請教單位負責元件上線的同事,同事提醒小喵,問小喵是否最近升級到Windows 7 SP1,這讓小喵驚覺,難道兇手就是他(所有人圍著Windows 7 SP1並用手指著它)。

 

小喵趕緊搜尋一下Windows 7 SP1的問題,發現了這篇文章中提到:Windows 7 SP1改了ADODB的IID,本來是【 {00000550-0000-0010-8000-00AA006D2EA4}】,將之改為【{00001550-0000-0010-8000-00AA006D2EA4}】,而這將影響著在Windows 7 SP1 以前的作業系統,在運作Windows 7 SP1所編譯出來的程式時,將因為找不到該程式內含的ADODB而造成無法正常運作。

 

解決方式之一:透過【Late Binding】方式使用ADO

小喵心想,當初小喵自己升級完Windows 7 SP1後,也寫了幾個元件,怎麼都沒事,將之前的程式翻出來與目前的比對一下,原來小喵以前都是用【Late Binding】的方式撰寫,而同事的元件則是以【Early Binding】的方式撰寫。小喵將之比較如下:

 

同事使用【Early Binding】的寫法:

需要先加入參考ADO的Library,然後宣告Connection的方式是:

程式運作時,會呼叫該程式所包含在內的元件來使用。好處是:

  1. 運作此元件或程式的主機不需要安裝元件(ADODB),就可以運作。
  2. 程式開發過程中,VB6會有Intellisense(按了.就會彈出相關的屬性函數可選擇)

不過如果該主機有更新的元件,是不會用更新的那個,因為指定了包在程式或元件裡面的。

 

而小喵使用【Late Binding】的寫法:

Set Conn = CreateObject("ADODB.Connection")

這樣的寫法在VB6裡面不會有Intellisense,而且運作時該運作的機器必須自己有相關的元件(ADODB),不過由於直接呼叫該程式所在機器中的元件來執行,所以如果該機器有新版本的元件,就會用新版本的來運作。

 

其他的方式

其他的解決方式,請參考這個這個KB【KB 2517589】,裡面有提到目前有未正式公開的HotFix或許可以處理。不過小喵是選擇暫時使用【Late Binding】方式來處理。未來如果有進一步的解決方式,再回頭來補充。

 

目前有正式的KB【KB2640696】可以解決這個問題,請依照作業系統的版本下載相對應的KB進行安裝就可以解決。

以下是簽名:


Microsoft MVP
Visual Studio and Development Technologies
(2005~2019/6) 
topcat
Blog:http://www.dotblogs.com.tw/topcat