我使用WiX工具集通过cmake和cpack从C ++代码库创建我的msi文件。这种设置在过去的6个月中效果很好,但现在我得到了零星的不良行为。
我的安装程序使用相同的升级代码卸载旧产品,以确保只安装了我的产品的一个版本(始终是主要升级)。我两天前向我的用户推出了最新版本(通过SCCM),在所有安装的10%中,我遇到了以下问题。
旧安装的卸载似乎有时是错误的。卸载过程会删除文件,但会保留根目录和bin目录,但会删除所有文件。当我通过WMI查询旧产品的安装时,它说它已安装,这很奇怪。其他90%的安装都很有效。我也无法在本地重现。
我有一个日志文件,但我不确定它是否来自行为不当的安装。
日志文件非常长,所以我只发布了一些让我持怀疑态度的片段。
MSI (s) (0C:9C) [15:21:35:083]: Component: CM_CP_runtime.bin.main2.exe;
Installed: Absent; Request: Null; Action: Null
...
MSI (s) (0C:78) [15:21:43:591]: Executing op: FileCopy(SourceName=-dbqfin2.dll|FreeImage.dll,SourceCabKey=CM_FP_runtime.bin.FreeImage.dll,DestName=FreeImage.dll,Attributes=512,FileSize=6201856,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=3.17.0.0,Language=1033,InstallMode=58982400,,,,,,,)
MSI (s) (0C:78) [15:21:43:591]: File: C:\Program Files\LDS Studio\bin\FreeImage.dll; To be installed; Won't patch; No existing file
动作:Null表示没有操作(但它应该是本地的),但我不确定原因。当我第二次开始安装时一切正常(因为没有旧版本)。一年前我有这种行为(但仅限于两个单个文件)当我们从Visual Studio移植到cmake并忘记将版本添加到我们的dll(之前的dll有一个版本,新版本没有版本,所以msi认为& #39;不是新版本,并在REINSTALLMODE默认模式下跳过它#omus')。从那时起,我们一直没有改变,一切正常,直到2天前。
这是我的wix_main.wxs文件
<Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
Name="$(var.CPACK_PACKAGE_NAME)"
Language="1033"
Version="$(var.CPACK_PACKAGE_VERSION)"
Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
<Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine"/>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="$(var.CPACK_WIX_UPGRADE_GUID)">
<UpgradeVersion
Minimum="1.0.0.0" Maximum="99.0.0.0"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no"
/>
</Upgrade>
<WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
<?ifdef CPACK_WIX_PRODUCT_ICON?>
<Property Id="ARPPRODUCTICON">ProductIcon.ico</Property>
<Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
<?endif?>
<?ifdef CPACK_WIX_UI_BANNER?>
<WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
<?endif?>
<?ifdef CPACK_WIX_UI_DIALOG?>
<WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
<?endif?>
<FeatureRef Id="ProductFeature"/>
<UIRef Id="$(var.CPACK_WIX_UI_REF)" />
<?include "properties.wxi"?>
<?include "product_fragment.wxi"?>
<CustomAction Id="RegisterExtensions"
FileKey="CM_FP_runtime.bin.main.exe"
ExeCommand="-regext"
Execute="deferred"
Return="check"
HideTarget="no"
Impersonate="no"
/>
<CustomAction Id="UnregisterExtensions"
FileKey="CM_FP_runtime.bin.main.exe"
ExeCommand="-unregext"
Execute="deferred"
Return="ignore"
HideTarget="no"
Impersonate="no"
/>
<InstallExecuteSequence>
<RemoveExistingProducts Before='InstallInitialize'>
NOT REMOVE
</RemoveExistingProducts>
<Custom Action="RegisterExtensions" After="InstallFiles">
NOT REMOVE
</Custom>
<Custom Action="UnregisterExtensions" After="InstallInitialize">
Installed AND (REMOVE = "ALL")
</Custom>
</InstallExecuteSequence>
</Product>
我发现了一些人们处理OnlyDetect模式的博文,但我不确定它是否可以帮助我,因为我无法在我的机器上重现它。 / p>
切换到REINSTALLMODE amus(https://msdn.microsoft.com/en-us/library/windows/desktop/aa371182(v=vs.85).aspx)也许是我最后的选择,但那将是我最后的选择。
我发现此博文https://jpassing.com/2007/06/16/where-to-place-removeexistingproducts-in-a-major-msi-upgrade/ =&gt;可能是我必须改变
<RemoveExistingProducts Before='InstallInitialize'>
NOT REMOVE
</RemoveExistingProducts>
到
<RemoveExistingProducts After='InstallInitialize'>
NOT REMOVE
</RemoveExistingProducts>
???
也许有人可以帮我解决这个问题
问候
通卡
答案 0 :(得分:0)
您看到的最可能的解释是RemoveExistingProducts(旧版产品的卸载)失败。这将导致回滚以恢复旧产品。然后安装旧产品,然后新产品继续安装。在某个时间点,新升级的安装将失败并回滚,这可能会损坏旧的已安装产品。这是在升级事务之外进行升级RemoveExistingProducts的一般问题。如果您的REP在InstallInitize之后,它将失败并且升级将不会继续。
(顺便说一句,如果您在InstallFinalize之后和升级的事务之外对REP进行排序,可能会发生同样的问题,因为您安装升级产品,事务结束,尝试卸载旧产品并失败,它会回滚并且恢复旧产品,现在您已安装旧产品和新产品。)
您需要创建升级的详细MSI日志,以了解REP失败的原因并保留旧产品的安装,以及新升级失败的原因(因为它会在程序和功能中显示)。将RemoveExistingProducts保留在升级的事务中也更安全。