在清单中需要哪些标签来注册免费COM? [英] Which tags are required in the manifest for registration free COM?

查看:129
本文介绍了在清单中需要哪些标签来注册免费COM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR regsvr32 产生的所有注册表项是否都需要存在于SxS reg-free-COM清单中,反之亦然?

TL;DR Do all registry entries produced by regsvr32 need to be present in a SxS reg-free-COM manifest and vice versa?

我试图为第三方组件获得免注册的COM。

I'm trying to get registration free COM going for a third party component.

阅读 up

Reading up on the subject, I find that there are several elements mentioned, that can be put into a manifest:

在文档中,我们可以添加以下内容标签添加到清单以描述COM组件:

From the docs, we can add the following tags to a manifest to describe a COM component:


  • assemblyIdentity 描述了抽象程序集,只要我能够告诉

  • comClass - 描述COM类(IID接口)。

  • typelib c $ c> comInterfaceExternalProxyStub - 何时?

  • comInterfaceProxyStub b
  • assemblyIdentity - which really just describes the "abstract assembly" as far as I can tell
  • comClass - describes the COM class (IID Interface). It would appear, this is always needed.
  • typelib - when?
  • comInterfaceExternalProxyStub - when?
  • comInterfaceProxyStub - when?

HKEY_LOCAL_MACHINE\SOFTWARE\Classes 的其他文档,我们可以观察到COM注册表项有几个类别:

From the other docs for HKEY_LOCAL_MACHINE\SOFTWARE\Classes we can observe that there are a few categories for the COM registry entries:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{CLSID} I assume roughly corresponds to comClass
  • HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{IID} would correspond to either comInterface[External]ProxyStub, but I have seriously no clue when to use which (or both)
  • Which regsitry entry corresponds with the typelib manifest entry ??

使用 regsvr42 提取我试图regfree的dll的东西产生一个只包含 comClass 条目,没有typelib或ProxyStub条目的清单。 (并且我交叉检查了写的关键的DLL, pdm.dll ,MS的进程调试管理器只写这些键,也就是没有类型库或代理stub info in the registry。)

Using regsvr42 to extract the stuff the dll I'm trying to regfree yields a manifest that only contains comClass entries, no typelib or ProxyStub entries. (And I cross checked the keys written, the DLL in question, pdm.dll, MS's Process Debug Manager only writes those keys, that is, there is no type library or proxy stub info apparent in the registry.)

如果注册表只包含与 comClass 相关的信息意味着该信息在SxS清单中将是足够的,或者在清单中需要额外的信息?

If the registry only contains the info that pertains to comClass does this then mean that this info will be sufficient in the SxS manifest, or may additional info be needed in the manifest?

除了我注意到注册表包含一个在结尾附加了版本号的 VersionIndependentProgId ProgId 。清单只有 ProgId 条目,并且文档状态为:

As an aside I noticed that the registry contains a VersionIndependentProgId and a ProgId that has a version number appended at the end. The manifest only has a ProgId entry, and the docs state:


progid :与
COM组件相关联的版本相关的编程标识符。 ProgID的格式是
< vendor>。< component>。< version>

但是文档还声明


comClass < progid> ...< / progid> 元素作为
子元素,列出版本相关的程序。

The comClass element can have <progid>...</progid> elements as children, which list the version dependent progids.

他们说 progid属性应该是版本独立的。

and they say that the progid attribute should be the version independent one.

那么,这里放什么?

推荐答案

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

The assemblyIdentity element is always required, part of the manifest plumbing. You must always provide the comClass element, it substitutes the HKLM\Software\Classes\CLSID registry key and is used to make the client's CoCreateInstance() call work. The file element names the COM server executable file.

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

The rest of the keys are optional, they are needed to make marshaling work. Marshaling occurs when the client call needs to be made on a different thread. That will always happen when the server and the client are in different processes, the case for an out-of-process server or when the server runs on another machine. And it can happen when the ThreadingModel specified in the comClass element demands it. In other words, when the COM object was created on one thread but is called on another and the server is not thread-safe.

RPC实现了编组,但它有一个工作做它需要帮助。它需要知道函数的参数,以及返回类型。因此,它可以将它们的值正确地串行化成可以通过网络传输或传递到另一线程中的代码的数据包,该线程进行调用。这是代理的工作。存根在接收端运行并反序列化参数以构建栈帧并进行调用。函数返回值以及通过引用传递的任何参数值然后返回到调用者。

RPC implements the marshaling but it has one job to do that it needs help with. It needs to know what the arguments for the function are, as well as the return type. So that it can properly serialize their values into a data packet that can be transmitted across a network or passed to the code in another thread that makes the call. This is the job of the proxy. The stub runs at the receiving end and deserializes the arguments to build the stack frame and makes the call. The function return value as well as any argument values passed by reference then travel back to the caller. The code that makes the call otherwise has no awareness at all that it didn't call the function directly.

有四种基本情况:


  • COM服务器不支持按这种方式调用,并且必须始终从创建它的同一个线程中使用。

  • The COM server doesn't support being called that way at all and must always be used from the same thread it was created on. Stop there, no need to add anything to the manifest.

COM服务器实现 IMarshal界面。当COM找不到另一种方法来编组调用时,由COM自动查询。这是非常罕见的,除了一个情况下,COM服务器聚合空闲线程marshaller。换句话说,是完全线程安全的,而不需要任何帮助,并始终在进程中运行。 PDM可能会这样工作。

The COM server implements the IMarshal interface. Automatically queried by COM when it cannot find another way to marshal the call. This is quite rare, except for a case where the COM server aggregates the free-threaded marshaller. In other words, is completely thread-safe by itself without needing any help and always runs in-process. PDM is likely to work that way. Stop there, no need to add anything to the manifest.

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

The COM server author started his project by writing the interface description of the server in the IDL language. Which was then compiled by MIDL. One option it has available is to auto-generate code from the IDL declarations, code that can be used to build a separate DLL that implements the proxy and the stub. IDL is sufficiently rich to describe details of the function argument types and usage to allow the marshaling to be done by this auto-generated code. Sometimes IDL attributes are not sufficient, the COM author then writes a custom marshaller. COM loads that DLL at runtime to create the proxy and stub objects automatically.

特定于COM自动化子集(IDispatch接口) marshaller知道如何封送满足子集需求的调用。很常见。它使用类型库来发现函数声明。

Specific to the COM Automation subset (IDispatch interface), Windows has a built-in marshaller that knows how to marshal calls that meet the subset requirements. Very common. It uses the type library to discover the function declaration.

后两个项目符号需要使用 HKLM \Software\Classes\Interface ,它具有每个接口的IID条目。这就是COM如何找到如何创建代理和接口的存根。如果它找不到密钥,那么它会回到IMarshal。您必须使用comInterfaceExternalProxyStub元素来替换注册表项。使用comInterfaceProxyStub是一种特殊情况,当代理和存根代码包含在COM服务器可执行文件中,而不是一个单独的文件。

The latter two bullets require using HKLM\Software\Classes\Interface, it has entries for the IID for every interface. That's how COM finds out how to create the proxy and the stub for the interface. If it cannot find the key then it falls back to IMarshal. You must use the comInterfaceExternalProxyStub element to substitute the registry key. Using comInterfaceProxyStub is a special case, that's when the proxy and stub code is included with the COM server executable instead of being a separate file. An option in ATL projects for example, turned on with the "Allow merging of proxy/stub" wizard selection.

最后一个项目符号也需要使用typelib元素,因此必须使用typelib元素。例如,在ATL项目中选择允许合并代理/存根向导选择。

The last bullet also requires using the typelib element, required so the built-in marshaller can find the type library it needs.

当COM客户端使用通过IDispatch的后期绑定时,需要progId,CreateObject()帮助函数客户端的运行时支持库是样板。用于任何脚本宿主例如。

The progId is required when the COM client uses late binding through IDispatch, the CreateObject() helper function in the client's runtime support library is boilerplate. Used in any scripting host for example.

有一些如何创建COM服务器的内部知识肯定有帮助,总是联系供应商或作者征求意见。它可以通过观察在服务器注册时写入的注册表项进行反向工程,但SysInternals的ProcMon工具是最好的方式。要查找的基本内容:

Having some insider knowledge of how the COM server was created certainly helps, always contact the vendor or author for advice. It can be reverse-engineered however by observing what registry keys are written when the server is registered, SysInternals' ProcMon tool is the best way to see that. Basic things to look for:


  • 如果看到它,请写入 HKLM \Software \Classes \Interface 键,那么您可以假设您必须提供comInterface | External | ProxyStub元素

  • If you see it write the HKLM\Software\Classes\Interface key then you can assume that you must provide the comInterface|External|ProxyStub element

00020420-0000-0000-C000-000000000046}为ProxyStubClsid32键,那么您可以假定它正在使用标准marshaller,并且必须使用comInterfaceExternalProxyStub元素以及typelib元素。您应该也看到它写入IID的TypeLib注册表项以及HKLM \Software \Classes\Typelib注册表项中的条目。后者给出了类型库的路径。几乎总是与COM服务器相同,嵌入类型库作为资源是非常常见的。如果它是单独的(.tlb文件),那么你必须部署它。

If you see it write {00020420-0000-0000-C000-000000000046} for the ProxyStubClsid32 key then you can assume it is using the standard marshaller and you must use comInterfaceExternalProxyStub element as well as the typelib element. You should then also see it write the IID's TypeLib registry key as well as the entry in the HKLM\Software\Classes\Typelib registry key. The latter gives the path of the type library. Almost always the same as the COM server, embedding the type library as a resource is very common. If it is separate (a .tlb file) then you must deploy it.

如果ProxyStubClsid32键值是另一个guid,那么你可以假设它使用它自己的代理/存根DLL。然后你应该看到它为代理写了CLSID键,它的InProcServer32键给你DLL的路径。如果该文件名匹配服务器的文件名,那么您可以假定代理/存根代码已合并,您必须改用comInterfaceProxyStub元素。如果没有,则必须使用comInterfaceExternalProxyStub,并且您必须部署DLL

If the ProxyStubClsid32 key value is another guid then you can assume it is uses its own proxy/stub DLL. You should then also see it write the CLSID key for the proxy, its InProcServer32 key gives you the path to the DLL. If that file name matches the server's file name then you can assume that the proxy/stub code was merged and you must use the comInterfaceProxyStub element instead. If not then comInterfaceExternalProxyStub is required and you must deploy the DLL

如果您看到它将ProgID写入 HKLM \Software \

If you see it write the ProgID in HKLM\Software\Classes then use the progid element, exactly as shown in the trace.

这篇关于在清单中需要哪些标签来注册免费COM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆