我已经实现了一个没有依赖性的自定义命令而没有任何问题。
但是这里是一个自定义命令,需要与其他四个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。
答案 0 :(得分:3)
MSI不提供这些服务,并且WiX不提供此类服务的扩展。我想,你可以为此目的写一个WiX扩展,但为什么呢?
MSI运行您的Type 1自定义操作,首先将二进制资源的副本提取到临时目录,然后调用该副本中的入口点,并(在完成自定义操作后)释放临时DLL拷贝。 (或者不是:MSI可能决定将该副本保留一段时间,作为优化,以防您稍后再调用其他入口点。但这取决于MSI,而不是您的代码。)
关键是二进制资源是暂时自动加载的...... 仅一个资源。这意味着您需要自定义操作来加载所需的任何其他资源。
您的自定义操作首先需要在二进制表上打开一个视图,从相应的记录中读取数据列作为流,并且将该数据缓冲区转储到某个文件,然后执行显式::LoadLibrary()
。然后::GetProcAddress()
关于您的自定义操作将从该加载的库调用的函数,并使用获取的指针来执行显式调用。最后,既然你是一个有礼貌的程序员,当你的自定义操作完成后,它需要在返回之前撕下所有这些基础设施:释放视图和库句柄,删除临时文件等。
如果所有这些看起来很麻烦,那么你是对的。非常简单的解决方案就是您拒绝的解决方案:静态链接您的custom_cmd.dll
。是的,这将使您的二进制文件和包含它的 .msi 稍微大一些(并且不会大得多,因为您可能不再需要单独的二进制副本依赖DLL的)。但这几乎是唯一的缺点。好处是你的自定义动作带有它完成任务所需的一切。
我经常在任何二进制文件上执行静态链接 - 不仅仅是自定义操作,而是自举程序等 - 在安装时运行,即使它们没有明确的外部依赖项。 (但当然它们有隐式,如Visual C ++运行时库等)。这样,我不仅知道我有我需要的资源,而且还有正确的版本这些资源,而不是客户之前可能安装的任何版本......或根本没有安装过。
您的安装包是一名提前无法了解其环境的侦察员。它可能是一个美国大城市......或者它可能是月球。或者Barsoom。不要以为你会有手机服务......或氧气。 随身携带!