如何防止 Wix 安装旧版本?

How to prevent Wix from installing an older version?

我有一个应用程序正在切换到 WiX 安装程序。到目前为止,几乎一切似乎都进展顺利。我遇到的一个问题是,如果下载并尝试安装旧版本,它会这样做。

这有点问题。如果安装了较新的版本,我不希望它安装旧版本。我认为问题出在 "Upgrade" 组件上,但我必须承认我碰壁了。我怎样才能更改它以便旧版本看到已经安装了更新版本而不安装它?

我的测试产品现在是 2.4 版(我们正在努力推出的最新版本)。它正确升级到 2.4.1 或 2.5 或 3.0。但是如果我制作一个 3.0 版本,然后 运行 2.4 的 msi 它仍然会添加它。

我的升级组件:

<Upgrade Id="PUT-GUID-HERE">
  <UpgradeVersion Maximum="2.4" Property="PREVIOUSVERSIONSINSTALLED" />
  <UpgradeVersion Minimum="1.0" Property="NEWERPRODUCTFOUND" OnlyDetect="yes" IncludeMinimum="no" />
</Upgrade>

跟进:
在遵循 Steins 的建议后,我得到了这样的错误
"Duplicate symbol 'WixAction:InstallExecuteSequence/RemoveExistingProducts' found"
在查看 <InstallExecuteSequence> 下的 Product.wxs 文件后,我不得不删除 <RemoveExistingProducts Sequence="6550" /> 因为那是它所指的副本。这样做之后安装程序就可以工作了,旧版本不能再安装在新版本之上。

过去的期货包:您不能更改包的旧版本以检测新版本。您需要从一开始就在您的包中建立保护。 Packages need to be pre-cognitive. It's an industry problem.

现代:你上面显示的WiX元素是"old-style"。这里有一个新的 "convenience feature" 描述:How do you detect installed product versions at each startup? It involves the "new" MajorUpgrade element. This new MajorUpgrade element 具有一些自动魔法,我相信它增加了您描述的默认保护(降级保护)。因此你可以切换到使用它。我会先试试看。让我内联基本标记:

<MajorUpgrade Schedule="afterInstallInitialize" 
              DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." 
              AllowDowngrades="no" AllowSameVersionUpgrades="no" />

除了删除旧式升级元素外,还请记住删除 RemoveExistingProducts 标准操作的任何硬编码调度。例如,删除此行(序列号可能不同,但名称相同):

<RemoveExistingProducts Sequence="6550" />

解耦:如果你发现存在很高的风险,人们会 运行 旧版本并乱用你最新的应用程序,你可以为你的最新版本设置一个新的安装位置和一个新的升级代码,并排安装以分离你的新旧产品。

Side-By-Side:要做到这一点,您的产品必须能够和平共存,而不是争夺文件关联、每台机器注册的 COM 服务器或其他使产品相互干扰的全球共享数据。这是否可能取决于您的应用程序。无法从两个不同的位置注册全局共享的 COM 服务器 - 如果您使用正常的注册表注册(尽管您可以使用基于清单的无注册 COM - 尽管有时会涉及)。在您的应用程序支持并行安装之前,可能需要克服许多挑战,或者如果您的包很简单且不涉及注册表,那么它可能会相当微不足道。

组件 GUID:除了提到的升级更改之外,您还需要为所有组件设置新的组件 GUID代码,以便真正将产品彼此屏蔽。如果您使用 WiX auto-GUIDs this will happen auto-magically. The reason you need new component GUIDs is attempted explained here: Change my component GUID in wix? 本质上,GUID 引用算作绝对安装位置,而不是文件本身。您安装到一个新位置,您需要一个新的组件 GUID。