WIX MSI从MSI创建的目录中的DLL库安装驱动程序会导致升级期间出现问题
1。导言 我已经通过WIX工具集构建了一个MSI安装程序。 此安装程序包含一个dll库和一个*.cab文件,用于在安装我的应用程序时安装第三方驱动程序。此过程通过以下步骤完成:my MSI在WIX MSI从MSI创建的目录中的DLL库安装驱动程序会导致升级期间出现问题,wix,windows-installer,Wix,Windows Installer,1。导言 我已经通过WIX工具集构建了一个MSI安装程序。 此安装程序包含一个dll库和一个*.cab文件,用于在安装我的应用程序时安装第三方驱动程序。此过程通过以下步骤完成:my MSI在INSTALLDIR中创建一个目录,然后通过执行所述dll中的延迟自定义操作将驱动程序安装到该目录中。我认为这种模式不是很有效,但这只是一个旁注 在升级过程中,MSI安装驱动程序的目录将被删除。当需要升级驱动程序时,这会导致问题,因为必须通过dll库中定义的另一个自定义操作进行升级,并且必须存在这些删除的文件
INSTALLDIR
中创建一个目录,然后通过执行所述dll中的延迟自定义操作将驱动程序安装到该目录中。我认为这种模式不是很有效,但这只是一个旁注
在升级过程中,MSI安装驱动程序的目录将被删除。当需要升级驱动程序时,这会导致问题,因为必须通过dll库中定义的另一个自定义操作进行升级,并且必须存在这些删除的文件。请注意:我无法在升级期间卸载和安装驱动程序,不幸的是,这是一个限制
2。解决方法
RemoveExistingProduct
是在InstallInitialize
之后计划的。
由于在升级过程中不能触摸驱动程序的文件,作为一种解决方法,我将RemoveExistingProduct
更改为在InstallExecute
之后执行,因此不会先删除文件,然后再安装,而是在需要时覆盖文件。我知道这是怎么回事
问题:这是一种适当/更好的处理方法(尽可能适当的解决方法)吗?它会引起一些不必要的副作用吗?到目前为止,我在日志中观察到:
不允许卸载组件:
{GUID-HERE}因为存在另一个客户端
另一个问题:这是预期的吗
3。详细信息和一些XML文件
始终会生成产品ID
和包ID
(“*”
)。升级代码在不同版本之间保持不变。重新安装模式=“omus”。
升级通过
元素完成:
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion OnlyDetect='no' Property='AUTO_FOUND_PREVIOUS'
Maximum='$(var.VersionNumber)' IncludeMaximum='no'
IgnoreRemoveFailure="yes" MigrateFeatures="yes" />
<UpgradeVersion OnlyDetect='no' Property='AUTO_FOUND_SELF'
Minimum='$(var.VersionNumber)' IncludeMinimum='yes'
Maximum='$(var.VersionNumber)' IncludeMaximum='yes'
IgnoreRemoveFailure="yes" MigrateFeatures="yes" />
<UpgradeVersion OnlyDetect='yes' Property='AUTO_FOUND_NEWER'
Minimum='$(var.VersionNumber)' IncludeMinimum='no' />
</Upgrade>
正如我提到的,安装驱动程序的目录也由我的MSI管理:
<DirectoryRef Id='INSTALLDIR_DRIVER'>
<Component Id='cmp_driverPlaceholderDir' Guid='{CONST-GUID-HERE}'>
<CreateFolder />
<RemoveFolder Id='INSTALLDIR_DRIVER' On='uninstall' />
</Component>
</DirectoryRef>
其他组件也有固定的guid
我也想听听如何正确处理自定义操作的外部驱动程序的安装,如果您对此有所了解,请不要犹豫。DIFX曾经是使用MSI安装驱动程序的“权威方法”,但现在已被Microsoft弃用。推荐的替代品称为
安装API
或设备和驱动程序安装参考
(取决于您需要的平台支持),但在Windows Installer的范围内,每种改进都更难使用(尽管我曾多次尝试编写一个WiX扩展来包装这些api,以帮助所有驱动程序编写人员),因为每当使用延迟自定义操作时,都需要维护MSI的事务性保证
当前的最佳实践(2021年初)是使用支持多个软件包的引导程序,并将安全地缓存您的软件包(以便在升级和卸载等过程中可以使用这些软件包),并让它同时安装您的驱动程序和MSI。您是否已经有引导程序?在安装后放置RemoveExistingProduct执行(我假设您没有使用InstallExecuteAgain,并且InstallExecute和InstallFinalize之间没有其他操作)可以,只要您严格遵守“组件规则”。我建议不要尝试修补(小升级和小更新是一堆蠕虫,你只有在绝对必要的时候才能涉入其中,即使这样,你也应该多问自己几次)。你提到的日志中的这一行很有可能是由于删除了以前的版本。“另一个客户端”是您刚刚安装的软件包。@B.Murri-是的,在
InstallExecute
和InstallFinalize
之间没有其他操作,只有RemoveExistingProduct
。在小升级和补丁的情况下:我从不这样做,一切都是作为大升级部署的。确实必须遵守组件规则。Driver安装确实是一个严重的困惑已经很长时间了。这有多难呢?这里是我之前的两个答案:(中间页的精华部分)还有。我想这些答案已经过时了。谢谢你的回答,B.Murri。看起来bootstrapper可能是最好的选择,我会试试。也谢谢Stein的投入,一如既往,你提供了知识和经验的最佳组合。