WIX MSI 从 MSI 创建的目录中的 DLL 库安装驱动程序会导致升级过程中出现问题

问题描述

1.简介

我通过 WIX 工具集获得了 MSI 安装程序版本。 此安装程序包含一个 dll 库和一个 *.cab 文件,用于在安装我的应用程序时安装 3rd 方驱动程序。此过程按以下步骤完成:我的 MSI 在 INSTALLDIR 中创建一个目录,然后通过从提到的 dll 执行延迟自定义操作来安装驱动程序。我认为这种模式并不是真正有效的模式,但这是一个旁注。

升级过程中,MSI 安装驱动程序的目录被删除。当需要升级驱动程序时,这会导致问题,因为它必须通过 dll 库中定义的另一个自定义操作完成,并且必须存在那些已删除文件。请注意:我无法在升级过程中卸载和安装驱动程序,很遗憾,这是一个限制。

2.解决方法

RemoveExistingProduct 安排在 InstallInitialize 之后。 由于在升级过程中不得触及驱动程序的文件,作为一种解决方法,我已将 RemoveExistingProduct 更改为在 InstallExecute后执行,因此不会先删除文件然后重新安装,而是如果需要,而是覆盖。我知道这affects the rollout procedures是如何发生的。

问题:这是处理它的正确/更好的方法(与解决方法一样正确......)吗?它会导致一些不必要的副作用吗?到目前为止,我在日志中观察到:

不允许卸载组件: {GUID-HERE} 因为存在另一个客户

一个问题:这是预期的吗?

3.详细信息和一些 XML

Product IDPackage ID 始终生成 ("*")。 UpgradeCode 在不同版本之间保持不变。 REINSTALLMODE="omus"升级是通过 <Upgrade> 元素完成的:

<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 弃用。推荐的替代品称为 Setup APIDevice and Driver Installation Reference(取决于您需要的平台支持),但每次演变在 Windows Installer 的范围内都更难使用(尽管我多次尝试编写包装这些 API 以帮助所有驱动程序编写者的 WiX 扩展),因为需要在使用延迟自定义操作时维护 MSI 的事务保证。

当前的最佳实践(2021 年初)是使用支持多个软件包的引导程序并安全地缓存您的软件包(以便它们在升级和卸载等期间可用),并让它安装您的驱动程序和 MSI .