使用WiX安装程序复制Visual Studio COM注册

曾几何时,一位年轻的,天真的工程师认为将自己的应用程序的一些function分离成用C#编写的COM组件是个好主意。 Visual Studio拥有所有的工具,对吧? .NET实际上是为此而做出的,对吧? 哈! 他说,这将是容易的。 我将有组件的体面的分离,使业务逻辑远离前端,并与COM,我将能够在任何地方使用它! 他愉快地在项目属性中检查了register for COM interopcheckbox的register for COM interop ,暴露了他想要的分类,然后继续前进。

哦,这样的select做出的审判。 现在这位年轻的工程师,更有经验的人现在不会希望这样的人了。 然而,他肩上的负担却是沉重的, 他希望减轻负荷。

WiX是一个用于从XML生成Windows Installer文件的工具。 这吸引了他 – 它可以很简单地复制一些正确的Windows安装程序文件所需的大部分代码,只需从less量configuration文件中复制即可。 他的目光正在抬头。

使用WiX 2.0,他可以轻松生成注册C#COM对象所需的文件。 这涉及到使用工具tallow。 他会做如下的事情:

 tallow -c -nologo MyComExposedLibrary.dll > MyComExposedLibrary.wxs 

(最初这是手动完成的,但最终我将这些步骤logging到一个小工具中,设置最终目录ref ID,组件ID,文件ID,GUID和代码库)。

然后,随后的安装程序将安装,如果应用程序工作,将会有欢乐的庆祝。

它没有。

这位年轻的工程师多年来一直在研发PC和testing安装PC的差异。 “所有registry项都是一样的!” 他会惊呼。 “MyComExposedLibrary的一切都注册了,我发誓!

除此之外,事实并非如此。

在第三天的黎明之后,他意识到还有另一个Visual Studio注册的对象,他的安装程序不是:MyComExposedLibrary.tlb文件。

显然,Visual Studio一直在注册这个文件,在HKLM\Software\Classes\Interfaceregistry项中创build其他子项,并在HKLM\SOFTWARE\Classes\TypeLib注册typelib。

Tallow没有任何帮助,抱怨说.tlb不是一个文件夹。 也不是WiX 3.0testing版 – 这似乎有更多的问题让事情工作。

我也给了热火一个尝试。 这生成了registry元素和类元素。 我清理了散热的输出,然后去编译它,但得到了一个不同的错误: error LGHT0130 : The primary key <uuid here> is duplicated in table 'Registry' 。 问题是,据我所知,uuid实际上并不存在于我的任何wxs源文件中。 如果我改变我的要素元素组件ref顺序,一个不同的dll组件给出了这个错误。 由于我没有成功将项目的WiX 3.0版本编译,所以我无法确认散热是否能提供正确的输出。

我从安装程序中删除了一切,除了导致出现此错误的程序集之外,并尝试再次编译。 我得到了同样的错误。 Arrugh!

所以,我的好友,Windows爱好者和WiX用户,有两个问题:

  • 是WiX可以本地注册的typelib吗? 如果是这样,怎么样?
  • 如果没有,用windows安装程序注册typelib的正确方法是什么?

另外,我猜这是另一部分,Visual Studio如何确定如何注册typelib? (编辑:看起来MSDN库文章typelib注册有所需的密钥的名称 ,但我仍然需要弄清楚如何获得uuid的(这是从这个博客文章typelib和COM登记由拉里奥斯特曼 。))多读一点,手动注册这些位可能会落在我的头上,但是我希望不要…

我评估了regasm /regfile:MyDll.dll MyDll.dll的输出。 它看起来像这些wix为dll生成的相同的密钥。 Regasm的其他模式, regasm /tlb:<filename>生成并注册组件的typelib,但是,

/ regfile [:FileName]使用指定的名称生成一个reg文件,而不是注册types。 该选项不能与/ u或/ tlb选项一起使用

似乎/ regfile开关与/ tlb开关不兼容。 Khaaaaaaaan!

进一步更新:看起来你并不需要包含.tlb文件。 根据wix的typelib元素的这个post ,MSI可以创build/注册这个作为设置过程的一部分。 这一切都归结为configurationWiX文档实际上通过获取正确的属性来安装它。

后来我发现,你可以直接在.tlb上使用热来获得正确的属性! 看到这个SO问题的更多信息 。

您应该使用位于正在使用的版本的bin目录中的Heat(WIX 3.0)。 看看这个博客post,我们在这里使用它来注册我们所有的COM对象,通过创build一个wix片段…

就像是

 heat file MyComExposedLibrary.dll -out MyComExposedLibrary.wxs 

之后,阅读你的编辑,我会用wix创build一个基本的msi,只安装com对象,看看是否有效…然后你就知道要攻击哪个战场了…

我最近遇到了这个问题,我可以在开发机器上find最简单的解决方法:

  1. 运行:Regasm MyDLL.dll /tlb:MyDLL.tlb
  2. 运行:加热文件MyDLL.dll -out MyDll-1.wxs
  3. 运行:加热文件MyDll.tlb -out MyDll-2.wxs

MyDll-2.wxs包含一个<Typelib> Typelib <Typelib>元素,您需要将其复制并嵌套在MyDll-1.wxs中生成的<File>元素中。 这会给你一个完整的<Component>元素,你可以在安装程序项目中使用。

为了提取COM信息,tallow将使用.NET框架附带的regasm.exe工具 。 当您启用“注册COM互操作”时,visual studio可能会使用相同的工具来注册程序集。

不同的是,tallow将使用regasm / regfile开关将信息发送到.reg文件,而不是实际注册程序集。 不幸的是regasm.exe生成的.reg文件不完整。 它跳过了在真实注册期间写入registry的typelib条目。 这可能是一个重蹈覆辙的错误。

为了让你的安装程序工作,你有三个select:

  1. 将缺less的registry项手动添加到tallow输出。 牛脂输出的目的是手动编辑,并保存与您的其他wxs文件无论如何。 你似乎试图完全自动生成一个工作的wxs文件,但我相信这永远不是一个牛脂的devise目标。

  2. 使用自定义操作从安装程序调用regasm。 这有点邪恶,因为你可能会失去一些由windows安装程序引擎提供的强大的交易保证。 我正在考虑在这里安装过程中由于故障而引发的回滚。

  3. 通过使用免注册的COM来避免注册。 这将需要为应用程序和COM库创build清单文件。

我知道这是一个老问题,但其他人可能会觉得这个有用…

经过自己的努力,我发现你可以通过使用tlbexp.exe捕获types库的信息,然后加热dll和tlb文件。 在你的wix项目中包括这两者的输出,你应该很好。

 tlbexp.exe dllFile.dll /out:dllFile.tlb heat.exe dllFile.dll ... heat.exe dllFile.tlb ...