我的产品曾经附带.vdproj
安装程序。在最新版本中,我使用WiX发布了一个带有完全重做安装程序的测试版(作为迁移到Visual Studio 2012的一部分,不再支持.vdproj)。不幸的是,当时我不知道升级代码应该在副本之间保持一致,并且已经发布了一个具有不同升级代码的beta安装程序。
我希望我的安装程序能够自动删除使用.vdproj
安装程序构建的先前版本,以及作为测试版副本发布的版本。这是我到目前为止的地方:
<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>
元素,但旧版本不会被删除。因此,新副本会尝试在旧副本之上安装,然后这两个版本都不再起作用。
Beta版和新版本的检测工作正常(<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中检测任一选项。
答案 0 :(得分:1)
我担心您无法在单个安装程序中同时处理2个不同的现有安装。此外,您不应该尝试卸载另一个产品(因为您的UpgradeCode和ProductCode不同,它是一个产品),因为msi无法同时安装。
我建议创建单独的exe应用程序(bootstrapper),它将运行以前安装的产品的子卸载过程,然后立即运行产品的安装(可能是在完整的UI模式下)。
要在没有用户交互的情况下卸载产品,请使用以下命令:
msiexec /x {ProductCode} /qn
我希望您了解以前安装的产品的ProductIds。如果没有,你可以找到它,搜索注册表:
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 documentation on upgrades。因此,您可能会进行次要升级或修补,直接在以前安装的文件之上安装新组件。这肯定会破坏应用程序。