1. 程式人生 > >糾錯《COM技術內幕》之ProgID

糾錯《COM技術內幕》之ProgID

string spa nbsp 大型軟件 查找 一個 cnblogs int 而且

最近在看《COM技術內幕》,看到第六章時發現該章節在解釋ProgID時有點錯誤,特此記錄一下,也給正在學習COM的小夥伴們一個提示。

而且我發現該問題存在於一些很多大型軟件的COM組件中。(開發者估計都是看了該書吧)

在該書的6.3.5章節講解了ProgID的在註冊表中的格式,示例如下

技術分享

註冊表文件格式為

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\AA.BB\CLSID]
@="{00000000-F2ED-4CD4-9204-A1C28871DD2E}"

[HKEY_CLASSES_ROOT\AA.BB\CurVer]
@="AA.BB.1
" [HKEY_CLASSES_ROOT\AA.BB.1\CLSID] @="{00000000-F2ED-4CD4-9204-A1C28871DD2E}"

(上面我故意將CLSID的第一節寫為零了,僅僅只是為了讀者容易區分後面的其他CLSID)

書中也講到了,這麽做的目的是為了客戶在使用COM組件時可以通過“AA.BB”這個與版本無關的ProgID來映射到最新版本的組件

在上例中也就是“AA.BB.1”這個版本。引用書中的一段原話“與版本號無關的ProgID關鍵字Helicopter.TailRotor包含兩個關鍵字CLSID及CurVer。”

也就是上面註冊表文件中所描述的格式。為了驗證書中所說的,我們把"AA.BB.1”的CLSID改一下

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\AA.BB\CLSID]
@="{00000000-F2ED-4CD4-9204-A1C28871DD2E}"

[HKEY_CLASSES_ROOT\AA.BB\CurVer]
@="AA.BB.1"

[HKEY_CLASSES_ROOT\AA.BB.1\CLSID]
@="{11111111-F2ED-4CD4-9204-A1C28871DD2E}"

那麽是不是真的可以通過“AA.BB”映射到“AA.BB.1”呢?編寫如下測試代碼

#include "stdafx.h"
#include 
<iostream> #include <Windows.h> int _tmain(int argc, _TCHAR* argv[]) { CLSID clsid; CLSIDFromProgID(L"AA.BB", &clsid); LPOLESTR str; StringFromCLSID(clsid, &str); std::wcout << str << std::endl; CoTaskMemFree(str); system("pause"); return 0; }

運行結果如圖

技術分享

很可惜,取到的CLSID還是“AA.BB”的,並非“AA.BB.1”的CLSID。

看到這裏你也許會發現,在我們的系統中,有著這個問題的COM組件有很多,比如迅雷的

技術分享

騰訊的

技術分享

它們都無法從“與版本號無關的ProgID”映射到“具體版本的ProgID”。

一般來說升級COM組件的最佳方式還是升級內部接口的方式,如IX2、IX3等,並不會選擇去添加一個新的COM組件的方式。

所以這個問題也不算是個問題。

回到正題,那麽如何做才是正確的呢?其實很簡單,只要把“AA.BB"的CLSID鍵刪除即可

Windows Registry Editor Version 5.00

[-HKEY_CLASSES_ROOT\AA.BB\CLSID]

[HKEY_CLASSES_ROOT\AA.BB\CurVer]
@="AA.BB.1"

[HKEY_CLASSES_ROOT\AA.BB.1\CLSID]
@="{11111111-F2ED-4CD4-9204-A1C28871DD2E}"

技術分享

這樣,CLSIDFromProgID才會真正的工作正常,再次運行測試程序得到”AA.BB.1“的CLSID

技術分享

CLSIDFromProgID會查找用戶指定的ProgID,如果其下有子鍵”CLSID“的話,則認為該ProgID是一個具體版本的。

否則該ProgID只是起到映射的作用,它實際會跳到”CurVer“鍵所指向的ProgID。

《COM技術內幕》中所講到的與版本無關的ProgID都添加了CLSID鍵,這樣會導致該ProgID不是一個能映射的ProgID。

轉載地址:http://blog.csdn.net/aqtata/article/details/36915823

糾錯《COM技術內幕》之ProgID