2

我有两个组件,其中一个组件具有simple.exe,另一个组件具有sample.dll一个 MSI。如果我同时安装 MSIsimple.exe并将sample.dll安装和在某个文件夹下的程序文件中,它有两个是.exe.dll。如果我对整个 MSI 进行重大升级,它会将在程序文件中创建的文件夹替换为新文件夹。.exe那么,如果我更改/提供文件更新,如何使 wix 不被替换.dll,反之亦然。在提供更新的同时,我将使用一些文件.dll注册和注销密钥。.bat请帮我解决我需要有条件的重大升级,当我更改它们时将替换特定文件。

请找到以下代码:

product.wxs

<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion = "0.0.4"?>
<?define ProductUpgradeCode = "d3170abf-b41c-4274-a3a0-85576052f35c"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="saranSample" Language="1033" Version="$(var.ProductVersion)" Manufacturer="example" UpgradeCode="$(var.ProductUpgradeCode)">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of product is already installed." AllowSameVersionUpgrades="no" AllowDowngrades="no" />
    <MediaTemplate EmbedCab="yes" />

<Upgrade Id="$(var.ProductUpgradeCode)">
  <UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
  <UpgradeVersion Minimum="0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<InstallExecuteSequence>
  <Custom Action="Filecleaner" After="InstallFinalize"></Custom>
</InstallExecuteSequence>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>

    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLFOLDER" Name="saranSample_$(var.ProductVersion)">
      <Component Id="exeFiles" Guid="12345678-1234-1234-1234-222222222222">
        <File Id="exe" Source="$(sys.CURRENTDIR)npp.7.5.7.Installer.exe" KeyPath="yes"/>
      </Component>
      <Component Id="dllFiles" Guid="12345678-1234-1234-1234-222222222223">
        <File Id="dll" Source="$(sys.CURRENTDIR)saran.dll" KeyPath="yes"/>
      </Component>
    </Directory>
        </Directory>
    </Directory>

<Feature Id="ProductFeature" Title="saranSample" Level="1">
  <ComponentRef Id="exeFiles"/>
  <ComponentRef Id="dllFiles"/>
</Feature>

4

2 回答 2

1

我支持菲尔的所有观点,也许我可以补充几点:

每个组件一个文件:确保您安装的每个文件都使用一个组件。我对所有文件类型都这样做,但你必须对二进制文件(dlls 和 exes)。这是为了使安装程序正确运行并符合 MSI 组件规则(Phil 提到)。我看到您有一个组件 EXE 文件和一个用于 DLL 文件的文件。为您添加到设置中的每个二进制文件创建新组件,并将二进制文件设置为组件的关键路径。


选择性文件更新:如果您想做的是在磁盘上保留旧版本的文件,同时以选择性的方式安装具有更高版本文件的新软件包,那么除了尝试设置文件只读(我从未尝试过 - 不知道会发生什么老实说)。您还可以设置一个空白组件 GUID(这样的 GUID 也称为Little Bobby Void-GUID”,只需查看这个非常官方的来源) - 这将安装一个或多个文件,并且永远不会再触摸或覆盖它们。如果组件键路径存在,还有一个组件标志可以设置为(我通常将它与永久设置组件结合起来)。也可以通过对您构建的 MSI 进行后处理来伪造文件的版本号。一些第三方工具,如 Installshield 和 Advanced Installer,在编译之前提供了一个 GUI 来执行此操作。

MSI 通常只会在设置中使用更高版本的二进制文件覆盖目标位置中的低版本文件(这是根据默认设置file versioning rules,可以通过设置自定义值来影响和修改REINSTALLMODE- 文件覆盖规则的“修饰符”) . 如果目标目标中的文件与正在安装的文件版本相同或更高,则不会覆盖目标(除非REINSTALLMODE设置为amus- 强制覆盖 - 这是一个可怕的概念并且有很多副作用)。

如果不明显:如果您的某些文件未针对给定版本更新,那么您只需包含旧设置中包含的这些文件的先前版本,它们将与您的文件一起显示在磁盘上有新版本。你不需要做任何事情来实现这一点,它会自动产生魔法。


后期重大升级:Phil 的第 3 点是关于重大升级的后期排序。这种重大升级不是卸载所有文件,然后重新安装它们,而是作为一个补丁有效地安装,比较旧包和新包之间的差异,并仅删除在最新包中删除的文件。所有其他文件都保留在磁盘上或根据文件覆盖规则进行适当更新。


保留设置文件:如果您有要在版本之间保留的设置文件,典型的问题是重大升级不会覆盖更改的非版本控制文件(文件覆盖规则不会覆盖更改的设置文件),但它会很高兴卸载并重新安装它们,除非它们在原始设置中被标记为永久 - 然后以原始状态重新安装它们,使它们看起来被覆盖(当它们实际被卸载和重新安装时 - 或者如果您愿意,可以恢复)。在我看来,这是一种技术反模式。

上述后期排序的主要升级功能/方法可以防止此设置文件还原问题,因为文件不会立即卸载和重新安装,而是在设置版本之间进行比较,并且如果它们是设置文件有更改则保持不变 - 前提是您已经实施了所有正确地根据 MSI 组件规则,这不是野餐。您需要 100% 的组件规则合规性以避免其他副作用,例如更新完成后丢失文件。关于组件规则的简短文章

或者,您可以在 MSI 中永久设置设置文件。然后它们将永远不会被卸载,但也可能永远不会更新并且永远不会卸载,除非您创建自己的构造来这样做。


路径变量$(sys.CURRENTDIR)对你有用吗?我喜欢为自己定义我自己的路径变量,我可以轻松地将其重新拉到我想要的任何文件夹:

<?define SourceFiles= "C:\Projects\MySetup\Releases\1.0.0\"?>

<...>

<Icon Id="Icon.exe" SourceFile="$(var.SourceFiles)\MyApp.exe" />

一些链接

于 2018-07-20T00:16:22.140 回答
0

一些东西:

  1. 为什么你有 MajorUpgrade 元素和 Upgrade 元素?MajorUpgrade 元素应该是您所需要的,所以它是令人困惑的事情。

  2. 与 MajorUpgrade 文档中一样,升级的默认顺序是 afterInstallValidate。这是升级的“早期”,在安装新版本之前有效地卸载了所有旧产品。这就是文件被删除(通过卸载)然后再次安装的原因。

  3. 看来您需要将 MajorUpgrade 计划设置为 afterInstallExecute。这会使用文件版本覆盖规则在旧文件上安装新产品文件。如果二进制文件的文件版本没有改变,那么它们将不会被替换。这种类型的升级程序还要求您遵循组件规则:

http://robmensching.com/blog/posts/2003/10/18/component-rules-101/

https://docs.microsoft.com/en-us/windows/desktop/msi/what-happens-if-the-component-rules-are-broken

另外,您提到使用 bat 文件进行注册,这不是必需的。WiX 具有 Heat 工具,用于在构建时提取注册,例如。

于 2018-07-19T18:11:57.153 回答