WiX创建了msi文件,奇怪的主要升级行为

时间:2017-11-15 06:13:21

标签: wix windows-installer cpack

我使用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>

???

也许有人可以帮我解决这个问题

问候
通卡

1 个答案:

答案 0 :(得分:0)

您看到的最可能的解释是RemoveExistingProducts(旧版产品的卸载)失败。这将导致回滚以恢复旧产品。然后安装旧产品,然后新产品继续安装。在某个时间点,新升级的安装将失败并回滚,这可能会损坏旧的已安装产品。这是在升级事务之外进行升级RemoveExistingProducts的一般问题。如果您的REP在InstallInitize之后,它将失败并且升级将不会继续。

(顺便说一句,如果您在InstallFinalize之后和升级的事务之外对REP进行排序,可能会发生同样的问题,因为您安装升级产品,事务结束,尝试卸载旧产品并失败,它会回滚并且恢复旧产品,现在您已安装旧产品和新产品。)

您需要创建升级的详细MSI日志,以了解REP失败的原因并保留旧产品的安装,以及新升级失败的原因(因为它会在程序和功能中显示)。将RemoveExistingProducts保留在升级的事务中也更安全。