2

我有一个产品,它曾经附带.vdproj安装程序。在最新版本中,我发布了一个测试版,其中包含使用 WiX 完全重做的安装程序(作为迁移到不再支持 .vdproj 的 Visual Studio 2012 的一部分)。不幸的是,当时我不知道升级代码应该在副本之间保持一致,并且已经发布了一个带有不同升级代码的 beta 安装程序。

我希望我的安装程序能够自动删除使用该.vdproj安装程序构建的先前版本,以及作为 beta 副本发布的版本。这是我到目前为止得到的地方:

<Product Id="{A4CBA9F9-D86B-400C-BD23-996B4367931A}" Name="Foo Viewer" Language="1033" Version="6.0.1.0" Manufacturer="Foo Corporation" UpgradeCode="43e024b8-b3ea-40a3-a854-2af83f207f0f">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

<MediaTemplate EmbedCab="yes" />

<Feature Id="FOOVIEWERFeature" Title="Foo Viewer" Level="1" Description="The Foo Viewer GUI and CLI binaries." AllowAdvertise="no" Absent="disallow" Display="expand">
<!-- Stuff -->
</Feature>

<PropertyRef Id="NETFRAMEWORK40CLIENT" />
<Condition Message="Foo Viewer requires the .NET Framework 4.0 Client Profile or higher to run.">Installed OR NETFRAMEWORK40CLIENT</Condition>

<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="FooViewerInstallerUI" />
<UIRef Id="WixUI_ErrorProgressText" />
<Icon Id="FooViewerIcon" SourceFile="../FooViewer.ico" />
<Property Id="ARPPRODUCTICON" Value="FooViewerIcon" />

<!-- I got this upgrade code by opening one of the old .vdproj MSIs in Orca -->
<Upgrade Id="{80539F30-8176-4DCC-A102-ED32A34A91CB}">
  <UpgradeVersion OnlyDetect="no"
                  Minimum="0.0.0.0"
                  IncludeMinimum="yes"
                  MigrateFeatures="no"
                  IgnoreRemoveFailure="no"
                  Property="UPGRADE_VDPROJ_FOOVIEWER"
                  />
</Upgrade>
<Upgrade Id="{43e024b8-b3ea-40a3-a854-2af83f207f0f}">
  <!-- Foo Viewer 6.0.0.0 (Beta) shipped with a version 5.3.0.0 in the installer. -->
  <UpgradeVersion OnlyDetect="no"
                  Minimum="5.3.0.0"
                  Maximum="5.3.0.0"
                  IncludeMinimum="yes"
                  IncludeMaximum="yes"
                  MigrateFeatures="yes"
                  IgnoreRemoveFailure="no"
                  Property="UPGRADE_WIX_FOOVIEWER"
                  />

  <!-- Detect newer versions -->
  <UpgradeVersion OnlyDetect="yes"
                  Minimum="6.0.1.0"
                  IncludeMinimum="no"
                  Property="NEW_VERSION_FOUND"/>
</Upgrade>
<Condition Message="A newer version of Foo Corporation Foo Viewer is already installed.">
  Installed OR NOT NEW_VERSION_FOUND
</Condition>
<InstallExecuteSequence>
  <RemoveExistingProducts Before="InstallInitialize" />
</InstallExecuteSequence>
</Product>

然而,尽管<upgrade>为旧安装程序的升级代码添加了一个元素,旧版本并没有被删除。结果,新副本尝试安装在旧副本之上,然后两个版本都不再工作。

测试版副本和较新版本的检测工作正常(<Upgrade使用 GUID {43e024b8-b3ea-40a3-a854-2af83f207f0f} )。测试版被卸载,如果我生成一个“更新”的安装程序,那么当前的安装程序不会正确安装。也就是说,WiX 安装程序相互检测没有问题。

我在这里做错了什么,不会让它检测到旧.vdproj安装的副本吗?

编辑:当发生这种情况时,我会记录安装过程的日志,我得到以下信息:

Action start 17:25:47: FindRelatedProducts.
MSI (c) (10:B8) [17:25:47:269]: FindRelatedProducts: current install is per-machine.  Related install for product '{2024FF03-D6F2-4065-A22B-80252B2A66B6}' is per-user.  Skipping...
Action ended 17:25:47: FindRelatedProducts. Return value 1.

这似乎是准确的。旧的安装程序提供了“每用户”或“每台机器”的选项,而新的安装程序总是强制每台机器。如果我在旧安装程序中选择“使用此计算机的所有人”,则新安装程序能够检测到它。如果可能,我想在 WiX 中检测任一选项。

4

1 回答 1

1

恐怕您不能在单个安装程序中同时处理 2 个不同的现有安装。此外,您不应尝试卸载另一个产品(因为您的 UpgradeCode 和 ProductCode 不同,它是另一个产品),因为 msi 无法同时安装。

建议创建单独的 exe 应用程序 (bootstrapper),它将运行以前安装的产品的子卸载过程,然后立即运行产品的安装(可能在完整的 UI 模式下)。

要在没有用户交互的情况下卸载产品,请使用以下命令:

msiexec /x {ProductCode} /qn

我希望您知道以前安装的产品的 ProductId。如果没有,你可以找到它,搜索注册表:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}\DisplayName

如果为单个用户安装了应用程序,则为 HKEY_CURRENT_USER。

注册表路径中提到的 {ProductCode} 是 GUID,它是您的 productCode。您应该检索“卸载”分支中的所有节点,并找到那些检查“DisplayName”属性的产品。我希望您至少知道所安装产品的名称 =)。并注意不要删除客户端机器上的所有软件 =)

请注意,如果您在 x64 机器上安装了 x86 应用程序,您应该搜索位置

HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}\DisplayName"

一个更重要的注意事项:如果您的引导程序也是 x86 应用程序,您应该检索没有“Wow6432Node”节点的节点,因为它将自动插入到请求的路径中。不同平台上的注册表项的精彩世界 =)。

请确保您的引导程序将以管理员权限运行或要求权限提升(它应包含安全清单)。

关于您帖子中问题的一个假设:也许您在更改 UpgradeCode 时没有更改 ProductCode?我不确定它会如何表现,但它绝对不是自动删除以前安装的产品的 MajorUpgrade。有关更多详细信息,请参阅有关升级的 Wix 文档。因此,您可能会获得次要升级或补丁,直接在先前安装的文件之上安装新组件。那肯定会破坏应用程序。

于 2012-12-04T16:04:04.093 回答