前一阵曾问过一个vs6下reg-free com的问题,后来实现了vs6下免注册COM使用。
目前该解决方案还没有碰到什么bug,不过从长远来看,是可能会出问题的。我们知道,com有个category的概念,它为应用程序创建不同类别的组件提供了便利。
然而,在使用免注册COM时,我找不到任何关于reg-free com category的资料,哪位有
reg-free com category的经验,指点一下。

解决方案 »

  1.   

    不在.NET环境下似乎是不可能的。
    事实上,对免注册组件的使用都是通过调用者的manifest中来指示组件位置和其它信息的,未在清单中指定的组件无法被加载(最起码位置都找不到),这个能力是.NET自己实现的,好像操作系统从XP SP2开始就支持免注册组件。category实际上不属于组件范畴,每个category对应一个宿主,具体解析过程是由各个宿主应用完成的,而不是COM库解析的。所以除非宿主自身支持免注册组件,或者它支持.NET,否则也没办法做到。如果这个category是你自己的应用程序作为宿主,那一点问题都没有,你可以用任何方式来读取信息,比如从组件manifest中读,或者从组件rgs资源中读,都可以,因为规则自己定。
      

  2.   

    现在情况是:在非.net环境下已经实现了reg-free com.
    唯一无法实现的就是com category.
    msdn中关于manifest的介绍中没有关于reg-free com category的key.以下from msdn.
    Element    Attributes     Required 
    comClass                  No 
               description    No 
               clsid          Yes 
               threadingModel No 
               tlbid          No 
               progid         No 
      

  3.   

    comClass Element下只有description,clsid,threadingModel,tlbid,progid这几个属性。没有用于描述category的。
      

  4.   

    <?xml version="1.0" encoding="utf-8"?>
    <asmv1:assembly 
       xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" 
       manifestVersion="1.0" 
       xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" 
       xmlns="urn:schemas-microsoft-com:asm.v2" 
       xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" 
       xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">   <asmv1:assemblyIdentity 
          name="TestApp.exe" 
          version="1.0.0.0" 
          language="neutral" 
          processorArchitecture="x86" 
          type="win32" />   <file name="TestCtrl.dll" 
            asmv2:size="20480" 
          xmlns="urn:schemas-microsoft-com:asm.v1">
          <comClass 
             clsid="{A501891B-BD12-437E-BAF1-4BC385C642D7}" 
             threadingModel="Apartment" 
             tlbid="{106D937A-9024-40BB-A7E6-81833ACFB2A3}" 
             progid="TestCtrl.Test" />
       </file>
    </asmv1:assembly>这是我的一个demo,其中应用程序TestApp.exe使用了TestCtrl控件(com control).
    在将TestCtrl 反注册后程序依然能运行。
    如果反注册后不使用该manifest文件,便无法运行。
    这就证实了,vs6可以使用reg-free com.
      

  5.   

    先问一句,组件的category到底属于哪一类?这个类别属于哪个应用管理?我查了一下资料,免注册组件从XP SP2和win2003开始都是支持的,这个含义应该是指COM库底层支持。如果有条件你在2000系统下试试能否成功,我从未使用过这个特性。
    category不属于COM管理范畴,属于宿主应用管理,有category的组件往往都是插件,但问题是插件都是动态添加的,宿主并不确定到底有哪些插件存在,所以不可能在静态manifest中添加动态插件的信息,一定需要从其它地方获得插件资料,除了注册表就是配置文件。对于你的TestApp应用来说,需要的TestCtrl组件是已知的,category根本没有存在的必要。
      

  6.   

    这个类别应该是由我的应用程序定义的。
    譬如TestApp,就可以定义CAT_MENU, CAT_TOOLBAR等多个类别,这样的好处是便于应用程序扩展。
    当用户想添加自己的Menu或ToolBar时,他们只需要实现相应的IMenu或IToolBar接口,并将组件类别注册成CAT_MENU或CAT_TOOLBAR即可。
    应用程序启动时去枚举CAT_MENU或CAT_TOOLBAR类别,就可以随机扩展了。
    对于TestApp应用来说,我可能向用户开放了不止一种接口,在这种情况下使用cagegory还是有必要的。
    如果用户开发了a,b,c,d,e,f,g七个库,其中有三个是用来扩展菜单的,有四个是用来扩展工具栏的,我如何知道哪三个是用来扩展菜单的呢?
    如果我知道a,e,f注册到了CAT_MENU,不就简单了吗?
    当然了,用户扩展了相应功能后,我需要提供一个工具用以修改manifest文件来告知application。至于windows2000,这个应该是不支持的,我没有win2k的环境,还没有试过。
      

  7.   

    这不是有点找麻烦吗,动态添加一个插件,需要填写某些信息以便你的应用找到它,三种方式你看哪种最合适:
    1、写注册表
    2、写配置文件
    3、修改TestApp.exe文件中的清单资源显然,无论如何,第三种是最不可取的解决方案。
      

  8.   

    对于常规COM,第一种是最方便的,直接注册成相应组件类别就可以了,虽然也写注册表吧,但是是由系统维护的。
    如果不使用COM,可以考虑使用配置文件。
    只有在不得不需要使用reg-free com的时候,才会使用第三种方案。另:清单文件本身也是配置文件,如果提供了修改清单文件的工具,第三种方案和第二种方案是一样的。
    相比之下,manifest可能简单一些,毕竟是纯xml的东西,配置文件不一定会被设计成什么样子。
    但是:现在问题是,我需要使用reg-free com.
      

  9.   

    外置清单还好解决,如果清单内置(存放到exe的资源里了)怎么办?虽然修改资源也是可以做到的,但直接修改exe文件总是不太好。2000系统优先读取外置清单,XP系统优先读取内置清单,以后的操作系统说不定会取消外部清单,这个是过渡的。
      

  10.   


    胡哥,你说的是,Microsoft官方也是这么说的。在 Windows XP 上,如果应用程序的本地文件夹中存在外部清单,则操作系统加载程序将使用此清单,而不使用二进制文件中嵌入的清单。在 Windows Server 2003 和 Windows 更高版本上,情况正好相反,即当存在嵌入的清单时,将忽略外部清单而使用嵌入的清单。
    不过我不担心这个,vs6差不多到尽头了,我们会考虑移植到高平台的。
      

  11.   

    那尝试一下UpdateResource吧,先把清单读出来,修改后再写回去,要保证exe当前没有被运行(锁定)
      

  12.   

    自己在exe中读取清单XML来解析有哪些插件