VB6寫的增益集在WIN7中執行的問題

VB6.0並沒有64bit的編譯器,所以基本上是無法編寫給64bit office 2010 使用的增益集,因為64位元的office只能使用64位元的增益集,所以很多使用者問到為什麼下載一些vb6.0所寫的增益集無法使用,通常是這個問題。

不過另外最近有使用者反應在32位元win7上安裝32位元的office 2007 或2010 一樣不能使用這些vb6.0所寫的COM型態的增益集,在安裝的過程中出現類似以下的錯誤訊息

image

註冊模組失敗的原因,有些網站上會說是因為沒有使用管理者權限去進行安裝,實際實驗的結果不管是不是管理者的身份去執行,都一樣會有這樣的問題,我原本的猜測是可能沒有安裝vb的執行環境的元件,可是把Visual Basic 6.0 Service Pack 6:Run-Time 轉散發套件 (vbrun60sp6.exe),下載安裝之後,一樣是不能執行,可見還有其他的原因,仔細的檢查Win7發現原來是少了MSADDNDR.DLL這個檔案,因為vb6寫的增益集用到此元件,而這個元件在安裝office2007或2010並沒有安裝到WIN7,所以導致上述的錯誤訊息,只要將此檔案安裝即可避免上述的問題。

另外有些安裝檔案的過程發生錯誤,雖然有移除但是殘留一些註冊機碼,導致後續的安裝無法正常執行出現以下之錯誤訊息。

image

此排除之方式就是要找出先前安裝的增益集的註冊機碼,將之刪除才能正常安裝。

關於增益集與Office版本配對問題

最近有網友來信問到很多增益集與Office版本配對的問題,其中最常問到的是應該要安裝32bit版本或64bit版本的增益集?隨著64位元的硬體越來越普及,現在很多人買電腦時,隨機安裝的作業系統很多是64bit的win7,而office2010也裝上64bit版本,導致很多32位元版本的增益集不能使用。

基本上現在64bit的win7是可以執行32位元的程式,所以很多32bit的程式還是能在64bit的win7跑,包括32bit的office。但是為什麼發生32位元版本的增益集不能使用,問題不在64bit的win7,而是在64bit的office2010無法與32bit增益集連結使用,所以解決的辦法就是在64bit的win7改安裝32bit的office2010,這樣就可以使用32bit的增益集,也就是說增益集的位元版本一定要和office的位元版本搭配,32bit的office只能使用32bit的增益集,64bit的office只能使用64bit的增益集。所以在64bit的win7之下可以執行用vb6寫的office增益集,原因是他安裝的office是32bit,但是他如果安裝的是64位元的office2010就無法使用。

如何設計出高效能的增益集?partII

在這幾個月一邊進行自己vb6的作品升級至vb.net的過程,vb6碼改成vb.net碼並不困難,但是比較麻煩的是一直被執行速度的問題所困擾,如果程式碼大一點,很明顯vb.net寫的增益集的執行速度在第一次執行時比vb6寫的慢很多,原因是vb6可以編譯成native code 發佈,而vb.net是在第一次執行時才即時編譯成native code,而每次重新執行office時都要vb.net所寫的增益集都要重新編譯,這樣的感覺對於使用者絕對不是好的經驗。一直在想微軟推這個.NET的架構難道只是要使用者要升級更高等級的硬體嗎?否則像一些硬體資源比較低階得電腦一裝上自己用VB.NET所寫的增益集,第一次執行可以說慢到想要打瞌睡,但是仔細一想,市面上很多用.NET開發的程式並沒有這樣嚴重的情況,而且很多程式看起來也蠻龐大的,所以問題應該不是.NET的問題,應該是自己沒有找到問題的關鍵。

隨著這幾個月的研究,才知道自己對於.NET FRAMEWORK 知識實在太淺了。在前一篇如何設計出高效能的增益集?PARTI 提到Just-in-time compilation的架構,自己卻不知道預編譯(Pre-Compile)的方法。在MSDN找了好久找到這一篇文章『逐步解說:使用自訂動作在安裝時將二進位編譯為機器碼』終於解決了我的問題,原來也可以讓.NET程式碼預先編譯為機器碼,讓程式不用每次執行都重新編譯。

舉例我有一個example.dll的增益集檔案,要使用這篇文章裏的範例程式將它預編譯,只要將範例專案程式一起封裝於安裝程式中加上安裝時的自訂動作屬性參數 /Args="[TARGETDIR]example.dll" ,便可以在程式安裝的過程將example.dll預先編譯為機器碼,並安裝至指定的目錄,執行程式時.net framwork會自動去此目錄載入預先編譯好的機器碼,而不會再執行編譯動作。

image

注意:

1.使用此篇文章的範例程式,記得將此程式編譯為32位元程式,不管是預編譯的對象是否為64位元。

2.可以在命令提示列利用 ngen.exe display "example.dll安裝的目錄" 檢查是否成功編譯。另外如果預編譯的對象是64位元的,記得要指定正確版本的ngen.exe,預編譯64位元的程式必須用64位元的ngen.exe,預編譯32位元的程式必須用32位元的ngen.exe,這兩個版本的ngen.exe是安裝在不同的目錄。像我的環境是64位元的環境ngen.exe就在C:\Windows\Microsoft.NET\Framework64\v4.0.30319\