以编程方式解析COM参考

时间:2013-06-23 16:47:01

标签: c# com msbuild

我正在尝试列出msbuild项目的所有引用及其在磁盘上的位置。

到目前为止,我可以很好地获得项目引用和程序集引用,但是我在使用COM引用时遇到了问题。这就是项目文件中大多数引用的样子:

<COMReference Include="[name of assembly]">
  <Guid>{GUID-GOES-HERE}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>primary</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>

我完全不知道如何获取COM DLL的路径。一些谷歌搜索告诉我,我可以查看HKEY_CLASSES_ROOT\CLSID\{GUID-FOUND-IN-PROJECT-FILE}\InprocServer32并获取密钥的默认值。当我使用regedit查看注册表时,它似乎是正确的,但每次我通过C#执行此操作时,注册表项始终为null。我也在Wow6432Node\CLSID下查看了相同的结果。

谷歌搜索进一步调高了msbuild ResolveComReference task以及我如何使用Microsoft.Build命名空间以编程方式使用msbuild(ResolveComReference class),但我只找到了如何使用这个命名空间来构建整个项目,而不是执行单个任务。

如何使用项目文件中的信息获取COM DLL的位置?

修改

这样做的原因是自动化我们的构建过程。一方面,这将让我们将COM DLL包含在我们的安装程序中(使用WiX的Heat工具或John Robbin的Paraffin工具)。另一方面,它可以解决我们与msbuild的问题。我们让msbuild解决所有依赖关系。如果Project1和Project2都引用相同的COM DLL而Project1引用Project2,它会崩溃,因为它试图添加两次COM DLL。

1 个答案:

答案 0 :(得分:6)

  

这样做的原因是自动化我们的构建过程

毫无疑问,这是问题的一部分。仅当在执行构建的计算机上安装COM服务器时,<COMReference>才是方便的。如果您想在另一台机器上重现构建,那将成为一个问题。在该机器上未安装正确的COM服务器的可能性大大增加。它当然可以解释为什么你无法在注册表中找到它。

为了使构建在任何机器上都可重现,打破构建依赖性变得非常重要。您可以通过运行Tlbimp.exe来创建导入库。并将其检入源代码管理中。并为生成的DLL添加常规程序集引用,以便您只具有简单的文件依赖性。

缺点是你将冻结依赖关系,并在COM服务器不断发展时遇到麻烦。 Boilerplate是当服务器版本发生变化时{guid}发生变化,这是避免DLL Hell所必需的。如果是这种情况,那么您将需要一个过程来确保在执行构建的所有计算机上注册COM服务器更新。在实践中这不是一个问题,因为具有COM依赖性总是意味着您还具有部署依赖性。您还需要确保服务器在用户的计算机上可用。这总是很重要,你几乎不会轻易改变版本。