如何执行具有依赖项的WiX自定义操作C ++ DLL文件?

时间:2013-01-18 13:44:54

标签: wix custom-action

我已经实现了一个没有依赖性的自定义命令而没有任何问题。

但是这里是一个自定义命令,需要与其他四个dll链接才能工作。

<Binary Id="libeay32"          SourceFile="..\bin\libeay32.dll"/>
<Binary Id="libintl"           SourceFile="..\bin\libintl.dll"/>
<Binary Id="libpq"             SourceFile="..\bin\libpq.dll"/>
<Binary Id="ssleay32"          SourceFile="..\bin\ssleay32.dll"/>
<Binary Id="custom"            SourceFile="..\bin\custom_cmd.dll"/>

  <CustomAction Id="cc_postgres" BinaryKey="custom" DllEntry="on_postgres_cmd" Execute="immediate" Return="check" HideTarget="no" />

我在安装时遇到以下错误

  

错误1723.此Windows Installer程序包存在问题。一个   无法运行此安装完成所需的DLL。联系   您的支持人员或包装供应商。行动cc_postgres,条目:   on_postgres_cmd,library:C:\ Users \ THE \ AppData \ Local \ Temp \ MSI17BB.tmp

如何在Wix中执行此操作,而无需在静态中重新编译所有内容。

THX。

1 个答案:

答案 0 :(得分:3)

MSI不提供这些服务,并且WiX不提供此类服务的扩展。我想,你可以为此目的写一个WiX扩展,但为什么呢?

MSI运行您的Type 1自定义操作,首先将二进制资源的副本提取到临时目录,然后调用该副本中的入口点,并(在完成自定义操作后)释放临时DLL拷贝。 (或者不是:MSI可能决定将该副本保留一段时间,作为优化,以防您稍后再调用其他入口点。但这取决于MSI,而不是您的代码。)

关键是二进制资源是暂时自动加载的...... 一个资源。这意味着您需要自定义操作来加载所需的任何其他资源。

您的自定义操作首先需要在二进制表上打开一个视图,从相应的记录中读取数据列作为流,并且将该数据缓冲区转储到某个文件,然后执行显式::LoadLibrary()。然后::GetProcAddress()关于您的自定义操作将从该加载的库调用的函数,并使用获取的指针来执行显式调用。最后,既然你是一个有礼貌的程序员,当你的自定义操作完成后,它需要在返回之前撕下所有这些基础设施:释放视图和库句柄,删除临时文件等。

如果所有这些看起来很麻烦,那么你是对的。非常简单的解决方案就是您拒绝的解决方案:静态链接您的custom_cmd.dll。是的,这将使您的二进制文件和包含它的 .msi 稍微大一些(并且不会大得多,因为您可能不再需要单独的二进制副本依赖DLL的)。但这几乎是唯一的缺点。好处是你的自定义动作带有它完成任务所需的一切。

我经常在任何二进制文件上执行静态链接 - 不仅仅是自定义操作,而是自举程序等 - 在安装时运行,即使它们没有明确的外部依赖项。 (但当然它们有隐式,如Visual C ++运行时库等)。这样,我不仅知道我有我需要的资源,而且还有正确的版本这些资源,而不是客户之前可能安装的任何版本......或根本没有安装过。

您的安装包是一名提前无法了解其环境的侦察员。它可能是一个美国大城市......或者它可能是月球。或者Barsoom。不要以为你会有手机服务......或氧气。 随身携带!