轉(zhuǎn)自:http://ajxfxb.blog.163.com/blog/static/56675086200911181118562/此問題以前一直沒有碰到過,因為VB建立的COM和ActiveX的工程,都是超級智能,什么都封裝好了,連組件注冊都幫你弄好了,而且VB沒有提供入口來修改這些屬性。
以前用VB建立這類工程,不需要關(guān)心這些細(xì)節(jié),也沒碰到過什么問題,因為的確,CLSID都是自動生成,不需要人為干涉。直到今天去上海大平洋保險出差,遇到金蝶OA系統(tǒng)的一個問題:編設(shè)出來的組件CLSID和已經(jīng)布署的系統(tǒng)的CLSID不一樣!
這下就出問題了,因為在完成測試新編譯出來的組件之前,我們不能把新改的組件布署上去(反正原因很復(fù)雜……)。最后是沒辦法,只好研究一下VB中是如何設(shè)置組件的CLSID的。
第一感覺就是VB建立工程的時候,用隨機算法算出一組CLSID,然后存在某個地方,因為只有這樣,每次編譯時,才能保證同一組CLSID。但是把工程目錄搜索了一遍,包括ASCII和二進(jìn)制搜索,都搜不出來,挨個挨個文件看也看不出。
只好研究VB的工程相關(guān)設(shè)置,也沒發(fā)現(xiàn),最后覺得有點令人懷疑的地方是所謂的VersionCompatiblity(“版本兼容”)。研究后終于搞清楚了其中來龍去脈。
VB的兼容卡中有三個設(shè)置:(工程屬性--部件--版本兼容)
1、NoCompatibility:不兼容,此設(shè)置下,每次編譯出的CoClass和Interface的CLSID都會不一樣。
2、ProjectCompatibility:工程兼容,此設(shè)置下,每次編譯出的CoClass的CLSID一樣,但I(xiàn)nterface的CLSID不一樣。
3、BinaryCompatibility:二進(jìn)制兼容,此設(shè)置下,保證每次編譯出的CoClass和Interface的CLSID都一樣。
當(dāng)選擇2和3時,還要在下面的Edit輸入框中輸入欲與其兼容的ocx文件。也就是說,要保證2和3,工程移動時必須把dll/ocx都要一起拷過來。否則編譯出來的COM對象CLSID就不一樣了。
如果丟失原來的ocx文件,就會彈出“Unalbe to set the version compatiblecomponent:XXXX”錯誤信息,你只能強制改為選項1不兼容,但此時你編譯出來的組件CLSID會重新生成,也就是說和原來的就不一樣了。
當(dāng)然,因為類型庫本來就以資源形式掛在dll/ocx中,所以你也可以直接修改二進(jìn)制文件。需要注意的是,資源文件中是以二進(jìn)制來存的,不是以ASCII碼來存的。
利用這些原理,也可以寫一個方便的插件來實現(xiàn)在VB中對組件CLSID的設(shè)置,有空寫一個:)。
另外,基于這種原因,如果使用VB編寫組件,使用方盡量使用ProgID,因為ProgID即VB中的子類名(.cls),也就是說,是可以很容易設(shè)定的。
愛華網(wǎng)



