繁体   English   中英

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

[英]WiX created msi file, strange major upgrade behaviour

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

行动:空意味着没有操作(但它应该是本地的),但是我不确定为什么。 当我第二次开始安装时,一切正常(因为没有旧版本)。 一年前,当我们从Visual Studio移植到cmake时,我曾有过这种行为(但仅用于两个文件),却忘记为dll添加版本(以前的dll有版本,新的dll没有版本,所以msi认为是不是新版本,请在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模式,但是我不确定它是否可以帮助我,因为我无法在计算机上复制它。

切换到REINSTALLMODE amus( https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa371182 ( v= vs.85).aspx)也许是我的最后选择,但这将是我的最后选择。

我发现此博客文章https://jpassing.com/2007/06/16/where-to-place-removeexistingproducts-in-a-major-msi-upgrade/ =>是否可能是我必须从

<RemoveExistingProducts Before='InstallInitialize'>
                NOT REMOVE
            </RemoveExistingProducts>

<RemoveExistingProducts After='InstallInitialize'>
                NOT REMOVE
            </RemoveExistingProducts>

???

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

问候
通卡

您所看到的最可能的解释是RemoveExistingProducts(旧产品的卸载)失败。 这将导致回滚,以还原该较旧的产品。 然后安装旧产品,然后新产品继续安装。 在某个时间点,新升级的安装将失败并回滚,这可能会损坏较旧的已安装产品。 这是在升级事务之外进行升级RemoveExistingProducts的普遍问题。 如果您的REP是在InstallInitize之后执行的,则它将失败并且升级将无法进行。

(顺便说一句,如果在InstallFinalize之后并在升级事务之外进行REP排序,则可能会发生类似的问题,因为安装升级产品,事务完成,尝试卸载较旧的产品并失败,它会回滚并还原较旧的产品产品,因此现在您已经安装了新旧产品。)

您需要创建升级的详细MSI日志,以查看REP为何失败并保留旧产品,以及新升级为何失败(因为否则它将显示在Program&Features中)。 同样,将RemoveExistingProducts保留在升级事务中也更安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM