2010-10-19 109 views
10

我想安装注册免费的COM,但有一个小问题,我另一个COM对象可能是客户端。注册免费的COM和DLL清单

APP.EXE -----> COM服务器/客户端DLL(注册与否)--------> COM服务器DLL(未注册)

我的问题是,是否有可能为第二个DLL(COM服务器/客户端DLL)创建一个清单?我没有可执行文件的控制权,但是如果我这样做了,如果我为可执行文件创建客户端清单并为COM服务器dll创建服务器清单,则这将起作用。

这是中间dll的清单文件。我试图嵌入它并尝试外部。仍然不起作用。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity type="win32" 
        name="COMCliSer.dll" 
        version="1.0.0.0" 
    /> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
        name="COMSer.dll" 
        version="1.0.0.0"      
     /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

在进一步的调查,我可以得到这一切工作,只要中间的DLL也是免费注册和exe有一个应用程序清单。只要我注册中间的DLL,并放弃应用程序清单(我没有控制什么exe将使用我的DLL),整个事情停止工作。

如果exe没有清单,那么dll的清单就没有考虑在内。我可以通过设置一切工作来证明这一点。然后在程序集清单中输入一个错误。该弹出通常的消息:

无法创建过程:此应用程序无法启动,因为应用程序配置不正确。重新安装该应用程序可能会解决此问题。

如果我然后删除应用程序清单,应用程序加载(尽管是CoCreateInstance的失败,因为它的依赖不会考虑)

+0

为什么你叫装配'comser.dll'?程序集清单信息是否合并?使用描述性名称部署程序集要容易得多,例如“Microsoft.VC90.CRT”,包含不同名称的dll:“msvcr90.dll”。在处理dll程序集时,由于单个清单现在有两个用途:调用程序集的内容给用户,以及描述程序集中dll的依赖关系,因此调试变得更加困难。 – 2010-10-20 12:41:24

+0

这些名字已经改变,以保护无辜!那些不是真名。这些是本机COM dll而不是.NET程序集。 – Steve 2010-10-20 13:31:30

+0

另外,“不起作用”算作什么?是否exe和第二个DLL加载,并简单地未能实例化第三,或exe的,或第二个DLL无法完全加载?让事情实际上无法加载是一个好的步骤,因为它意味着系统正在查看清单,并至少将错误记录到系统或应用程序事件日志中。如果它简单地失败了对CoCreateInstance的调用,那么它可能根本看不到该清单。 – 2010-10-20 15:57:52

回答

5

只需添加一个组件依赖于客户端/服务器DLL的清单指向com服务器DLL。

请记住,程序集清单与“应用程序”清单不同:程序集清单描述程序集:给它一个名称,并列出它的dll。 应用程序清单是RT_MANIFEST嵌入式资源,它描述了当前模块的依赖关系。

所以,说到底,你会:

  • APP.EXE,与外部(app.exe.manifest)或描述在组装的依赖嵌入式RT_MANIFEST称为“acme.clientserver”
  • acme.clientserver.manifest描述一个程序集,并将'clisrv.dll'列为注册免费的com dll。
  • clisrv.dll,与外部(clisrv.dll.2.manifest)或嵌入RT_MANIFEST,描述上称为 'acme.server'
  • acme.server.manifest的组件的依赖性,描述一个组件,列出SERV .dll作为注册免费的COM DLL。
  • serv.dll - 可能或者可能不会有一个清单列出更多的依赖程序集。

这在技术上是可以调用的DLL名称的装配,并合并双方的装配和DLL体现一起 - Win32加载器支持这一点,但一些设置,在应用程序清单是有效的不是装配清单有效,这可能导致生成的程序集无法加载。这也使数字签名非常困难。


WRT exe必须有一个清单:通常exe的清单设置进程默认激活上下文。我不能100%确定当exe没有清单时windows如何运行,但我很确定dll中的清单仍然会被处理。

这意味着问题归结为CoCreateInstance中缺少隔离支持 - 出于某种原因 - 默认情况下 - CoCreateInstance仅在reg free com条目的默认激活上下文中查找。

重写它是手动建立自己的激活上下文,使用Activation Context API

的基本方法是调用方式:

  • CreateActCtx - 创建一个从您的dll文件清单的激活上下文。
  • ActivateActCtx - 激活上下文
  • CoCreateInstance - 现在将搜索reg free com条目的当前激活上下文。
  • DeactivateActCtx - 恢复默认激活上下文。

您可以添加/ d ISOLATION_AWARE_ENABLED包装由活化的上下文实现的,由于某种原因,CoCreateInstance的大多数Windows调用不裹:/

+0

我没有app.exe.manifest(不需要它,因为中间的COM DLL已注册)。我试图给中间的dll添加一个清单,但无济于事。 – Steve 2010-10-20 10:34:34

+0

你是否在资源编辑器(例如visual studio)中打开了中间的dll文件,看看它是否具有RT_MANIFEST资源以及它的内容? VS始终将RT_MANIFESTS显示为十六进制,因此您需要将其导出为将其作为文本进行查看。 – 2010-10-20 10:37:02

+0

好的,那样做。该DLL有两个RT_Manifest,我想是由编译器(Delphi)将Windows公共控件命名为依赖关系,另一个是我添加的上面显示的那个。 – Steve 2010-10-20 11:05:48