C++ 无注册COM的清单中需要哪些标记?

C++ 无注册COM的清单中需要哪些标记?,c++,com,manifest,side-by-side,regfreecom,C++,Com,Manifest,Side By Side,Regfreecom,TL;DR是否所有由regsvr32生成的注册表项都需要存在于SxS reg免费COM清单中,反之亦然 我正在尝试让第三方组件的免注册COM正常运行 关于这个主题,我发现有几个元素可以放在清单中: ,我们可以向清单中添加以下标记来描述COM组件: assemblyIdentity——据我所知,它实际上只是描述了“摘要” comClass-描述COM类(IID接口)。看起来,这总是需要的 typelib-什么时候 ComInterfaceExternalProxySub-什么时候 ComInt

TL;DR是否所有由
regsvr32
生成的注册表项都需要存在于SxS reg免费COM清单中,反之亦然


我正在尝试让第三方组件的免注册COM正常运行

关于这个主题,我发现有几个元素可以放在清单中:

,我们可以向清单中添加以下标记来描述COM组件:

  • assemblyIdentity
    ——据我所知,它实际上只是描述了“摘要”
  • comClass
    -描述COM类(IID接口)。看起来,这总是需要的
  • typelib
    -什么时候
  • ComInterfaceExternalProxySub
    -什么时候
  • ComInterfaceProxySub
    -什么时候
我们可以观察到COM注册表项有几个类别:

  • 我假设大致对应于
    comClass
  • 将对应于
    comInterface[External]ProxySub
    ,但我严重地不知道何时使用哪个(或两者都使用)
  • 哪个regsity条目对应于
    typelib
    manifest条目
使用来提取我试图释放的dll的内容会生成一个清单,其中只包含
comClass
条目,没有typelib或ProxyStub条目。(我交叉检查了已写入的键,有问题的DLL,
pdm.DLL
,MS的Process Debug Manager只写入这些键,也就是说,注册表中没有明显的类型库或代理存根信息。)

如果注册表仅包含与
comClass
相关的信息,那么这是否意味着该信息在SxS清单中足够,或者清单中可能需要其他信息


顺便说一句,我注意到注册表包含一个
VersionIndependentProgId
和一个
ProgId
,在末尾附加了一个版本号。清单只有一个
ProgId
条目,文档状态为:

progid:与 COM组件。ProgID的格式是

但文件也指出

comClass元素可以有
元素作为 子项,列出与版本相关的程序ID

progid属性应该是独立于版本的属性


那么,在这里放什么?当客户端不请求特定版本时,这是否重要?

始终需要assemblyIdentity元素,它是清单管道的一部分。必须始终提供comClass元素,它替代
HKLM\Software\Classes\CLSID
注册表项,并用于使客户端的CoCreateInstance()调用正常工作。file元素命名COM服务器可执行文件

其余的键是可选的,它们是编组工作所必需的。当需要在不同的线程上进行客户端调用时,会发生封送处理。当服务器和客户端处于不同的进程中时,总是会发生这种情况,例如进程外服务器或服务器在另一台机器上运行时。当comClass元素中指定的ThreadingModel需要时,可能会发生这种情况。换句话说,当COM对象是在一个线程上创建的,但在另一个线程上被调用,并且服务器不是线程安全的

RPC实现封送处理,但它有一个需要帮助的作业要做。它需要知道函数的参数是什么,以及返回类型。因此,它可以正确地将它们的值序列化为数据包,这些数据包可以通过网络传输,或者传递给另一个线程中进行调用的代码。这是代理的工作。存根在接收端运行,并反序列化参数以构建堆栈帧并进行调用。函数返回值以及通过引用传递的任何参数值随后返回调用方。否则进行调用的代码根本不知道它没有直接调用函数

有四种基本情况:

  • COM服务器根本不支持以这种方式调用,必须始终从创建它的同一线程使用它。到此为止,无需在清单中添加任何内容

  • COM服务器实现了。当COM找不到其他封送调用的方法时自动查询。这是非常罕见的,除了COM服务器聚合自由线程封送拆收器的情况。换句话说,它本身是完全线程安全的,不需要任何帮助,并且总是在进程中运行。PDM很可能就是这样工作的。到此为止,无需在清单中添加任何内容

  • COM服务器作者通过用IDL语言编写服务器的接口描述开始了他的项目。然后由MIDL编译。它提供的一个选项是从IDL声明自动生成代码,该代码可用于构建实现代理和存根的单独DLL。IDL足够丰富,可以描述函数参数类型和用法的详细信息,从而允许自动生成的代码完成封送处理。有时IDL属性不够,COM作者会编写一个自定义封送拆收器。COM在运行时加载该DLL以自动创建代理和存根对象

  • 特定于COM自动化子集(IDispatch接口),Windows有一个内置封送器,它知道如何封送满足子集要求的调用。非常普遍。它使用类型库来发现函数声明

后两个项目符号需要使用
HKLM\Software\Classes\Interface
,每个接口都有IID条目。COM就是这样发现如何为接口创建代理和存根的。如果是