zoukankan      html  css  js  c++  java
  • 纠错《COM技术内幕》之ProgID

    近期在看《COM技术内幕》,看到第六章时发现该章节在解释ProgID时有点错误,特此记录一下,也给正在学习COM的小伙伴们一个提示。

    并且我发现该问题存在于一些非常多大型软件的COM组件中。(开发人员预计都是看了该书吧)


    在该书的6.3.5章节解说了ProgID的在注冊表中的格式,示比例如以下




    注冊表文件格式为


    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOTAA.BBCLSID]
    @="{00000000-F2ED-4CD4-9204-A1C28871DD2E}"
    
    [HKEY_CLASSES_ROOTAA.BBCurVer]
    @="AA.BB.1"
    
    [HKEY_CLASSES_ROOTAA.BB.1CLSID]
    @="{00000000-F2ED-4CD4-9204-A1C28871DD2E}"

    (上面我有益将CLSID的第一节写为零了,只不过为了读者easy区分后面的其它CLSID)

    书中也讲到了,这么做的目的是为了客户在使用COM组件时能够通过“AA.BB”这个与版本号无关的ProgID来映射到最新版本号的组件

    在上例中也就是“AA.BB.1”这个版本号。引用书中的一段原话“与版本号号无关的ProgIDkeywordHelicopter.TailRotor包括两个keywordCLSID及CurVer。”

    也就是上面注冊表文件里所描写叙述的格式。为了验证书中所说的,我们把"AA.BB.1”的CLSID改一下


    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOTAA.BBCLSID]
    @="{00000000-F2ED-4CD4-9204-A1C28871DD2E}"
    
    [HKEY_CLASSES_ROOTAA.BBCurVer]
    @="AA.BB.1"
    
    [HKEY_CLASSES_ROOTAA.BB.1CLSID]
    @="{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组件的方式。

    所以这个问题也不算是个问题。


    回到正题,那么怎样做才是正确的呢?事实上非常easy,仅仅要把“AA.BB"的CLSID键删除就可以


    Windows Registry Editor Version 5.00
    
    [-HKEY_CLASSES_ROOTAA.BBCLSID]
    
    [HKEY_CLASSES_ROOTAA.BBCurVer]
    @="AA.BB.1"
    
    [HKEY_CLASSES_ROOTAA.BB.1CLSID]
    @="{11111111-F2ED-4CD4-9204-A1C28871DD2E}"



    这样,CLSIDFromProgID才会真正的工作正常,再次执行測试程序得到”AA.BB.1“的CLSID




    CLSIDFromProgID会查找用户指定的ProgID,假设其下有子键”CLSID“的话,则觉得该ProgID是一个详细版本号的。

    否则该ProgID仅仅是起到映射的作用,它实际会跳到”CurVer“键所指向的ProgID。


    《COM技术内幕》中所讲到的与版本号无关的ProgID都加入了CLSID键,这样会导致该ProgID不是一个能映射的ProgID。




  • 相关阅读:
    [Leetcode 11] 112 Path Sum
    [Leetcode 14] 7 Reverse Integer
    [Leetcode 12] 126 Word Ladder II TO_BE_ADDED
    [Leetcode 13] 1 Two Sum
    [Leetcode 7] 101 Symmetric Tree
    [Leetcode 9] 110 Balanced Binary Tree
    [Leetcode 15] 8 String to Integer (atoi)
    [Leetcode 8] 104 Maximum Depth of Binary Tree
    [Leetcode 16] 9 Palindrome Number
    [Leetcode 10] 111 Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4212605.html
Copyright © 2011-2022 走看看