【问题标题】:Wix - Upgrade always runs older installer msi and fails in trying to read old msiWix - 升级总是运行较旧的安装程序 msi,但无法尝试读取旧的 msi
【发布时间】:2011-02-16 13:41:30
【问题描述】:

我遇到了安装程序的 Windows 缓存问题。我正在尝试进行升级,每次 Windows 安装程序启动旧版本的安装程序时。当我进行升级时,它抱怨读取旧版本的 msi 文件时出现问题(因为它不再位于同一目录中)。

我确实更改了 UpgradeCode 和 ProductCode 但保持 PackageCode 相同。我也有不同的 ProductVersion 代码(2.2.3 与 2.3.0)。

这是我的代码示例:

<Upgrade Id="$(var.UpgradeCode)">
      <UpgradeVersion Property="OLDAPPFOUND"
                  IncludeMinimum="yes"
                  Minimum="$(var.RTMProductVersion)"
                  IncludeMaximum="no"
                  Maximum="$(var.ProductVersion)"/>
  <UpgradeVersion Property="NEWAPPFOUND"
                  IncludeMinimum="no"
                  Minimum="$(var.ProductVersion)"
                  OnlyDetect="yes"/>
</Upgrade>

这是安装顺序:

<InstallExecuteSequence>
    <Custom Action='SetUpgradeParams' After='InstallFiles'>Installed AND NEWAPPFOUND</Custom>
      <Custom Action='Upgrade' After='SetUpgradeParams'>Installed AND NEWAPPFOUND</Custom>
   </InstallExecuteSequence>

我得到的错误是:

尝试读取文件时发生网络错误:

谢谢,

【问题讨论】:

    标签: installation wix windows-installer upgrade


    【解决方案1】:

    保持不变PackageCode

    您真的希望自动生成它...参考文档:

    不同的 .msi 文件不应 具有相同的包代码。它是 更改包代码很重要 因为它是主要标识符 安装程序用于搜索 并验证正确的包 给定的安装。如果一个包是 不改包就改了 代码,安装程序可能无法使用 如果两者都还在,则更新的包 安装程序可以访问。

    这是我们生产环境中的一个示例...

    <Product Id="*"
             UpgradeCode="$(var.Property_UpgradeCode)"
             Name="!(loc.ApplicationName)"
             Language="!(loc.Property_ProductLanguage)"
             Version="$(var.version)"
             Manufacturer="!(loc.ManufacturerName)" > 
    
    <Package Description="!(loc.Package_Description) $(var.version)"
       Comments="!(loc.Package_Comments)"
       Manufacturer="!(loc.ManufacturerName)"
       InstallerVersion="301"
       Compressed="yes"
       InstallPrivileges="elevated"
       InstallScope="perMachine"
       Platform="$(var.ProcessorArchitecture)" />
    

    现在这种方法的缺点是它意味着您可能还想强制执行主要升级,它只关心被引用的升级代码。现在我们可以利用这样一个事实,即对于 Windows Installer 软件包,只有前三个字段是重要的,例如1.0.0.1 和 1.0.0.2 都被解释为 1.0.0(这在文档中明确提到,所以我们可以依赖它。)

    扩展此逻辑,我们可以在每个构建时自动增加(忽略的)第四个版本字段,但在前三个相同时阻止升级。

        <UpgradeVersion Property="ANOTHERBUILDINSTALLED"
                 Maximum="$(var.version)" Minimum="$(var.version)"
                 IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="yes" />
    

    好处是这对客户完全透明,但会阻止内部测试/QA 团队在另一个“构建”之上安装一个“构建”,您还需要确保在任何公开发布后立即手动增加前三个中的一个版本字段。

    【讨论】:

    • 感谢大家的回复。我想出了一种不同的升级方法。问题是我们的升级不使用默认的 Windows Installer 升级,而是执行 JavaScript 中详述的自定义操作。无论哪种方式,我现在都遇到了不同的问题。我不知道我是否需要一个新线程或者是否有人可以在这里帮助我:
    • 我们的旧安装程序不支持升级并且不包含“升级”按钮。较新的安装程序支持其自己的带有较新品牌图像的升级版本。问题在于启动新的 msi。我得到了新的品牌图像,但安装程序中没有显示升级按钮?!阅读日志,我还可以看到它正在启动旧的 msi 的 WIX UI 代码。 Windows Installer 是否有理由从新的 msi 和旧的 msi 中选择要显示的内容?!我怎样才能摆脱旧 msi 的缓存?!谢谢,
    【解决方案2】:

    你的产品元素说明了什么?

    需要在升级表和产品表中指定相同的升级码即

    <Product 
       Id="..." 
       Language="..." 
       Manufacturer="..." 
       Name="..." 
       UpgradeCode="$(var.UpgradeCode)" 
       Version="..."
    >
    

    如果最初没有指定它,它也需要在原始版本中,那么也许您可以运行 CA 以使用 shell 命令将其删除。

    除此之外一切都还好。

    在日志中“查找相关产品”部分是否说明了什么?

    【讨论】:

      【解决方案3】:

      这是源代码(或尽可能多的):

      http://schemas.microsoft.com/wix/2003/01/wi'>

      .....

      <Package Id='$(var.PackageCode)'
               Comments='$(var.App_LongName)'
               Description='$(var.App_LongName) setup package'
               Manufacturer='$(var.Manufacturer)'
               InstallerVersion='200'
               Languages='1033'
               SummaryCodepage='1252'
               Compressed='yes'
               Keywords='Installer,$(var.App_ShortName)' />
      
      <FragmentRef Id='AppInstaller.UI' />
      
      <!-- Upgrade table -->
      <Upgrade Id="$(var.UpgradeCode)">
      
        <UpgradeVersion Minimum="$(var.ProductVersion)"
                        IncludeMinimum="no"
                        OnlyDetect="yes"
                        Property="NEWPRODUCTFOUND" />
        <UpgradeVersion Minimum="$(var.RTMProductVersion)"
                        IncludeMinimum="yes"
                        Maximum="$(var.ProductVersion)"
                        IncludeMaximum="no"
                        Property="UPGRADEFOUND" />
      
      </Upgrade>
      
      .....
      
      
      <!-- Prevent downgrading -->
      <CustomAction Id="NewerVersionDetected" Error="$(loc.App_WixUI_NewerVersionDetected)" />
      
      ......
      
      <CustomAction Id="SetDeployParams" Return="check" Property="Deploy" Value="Deploy|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
      <CustomAction Id="Deploy" JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
      <CustomAction Id="SetRollbackParams" Return="check" Property="RollbackDeploy" Value="Rollback|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
      <CustomAction Id="RollbackDeploy" JScriptCall="main" Property="Script" Execute="rollback" />
      <CustomAction Id="SetUnDeployParams" Return="check" Property="UnDeploy" Value="Undeploy|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
      <CustomAction Id="UnDeploy" JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
      <CustomAction Id="SetRepairParams" Return="check" Property="Repair" Value="Repair|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
      <CustomAction Id="Repair" JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
      <CustomAction Id="SetUpgradeParams" Return="check" Property="Upgrade" Value="Upgrade|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
      <CustomAction Id='Upgrade' JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
      <CustomAction Id="PreventDowngrading" Error="Newer version already installed." />
      
      <InstallUISequence>
        <FindRelatedProducts Sequence="200" />
        <Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
      </InstallUISequence>
      
      <InstallExecuteSequence>
        <LaunchConditions After='AppSearch'></LaunchConditions>
        <RemoveExistingProducts After='InstallFinalize' />
      
        <Custom Action='SetUrl' Before='InstallFiles' />
        <Custom Action='SetSecurePort' After='LaunchConditions'>PROTOCOL = "secure"</Custom>
        <Custom Action='SetNonSecurePort' After='LaunchConditions'>NOT (PROTOCOL = "secure") OR NOT PROTOCOL</Custom>
      
        <Custom Action='SetDeployParams' After='InstallFiles'>NOT Installed AND NOT PATCH</Custom>
        <Custom Action='Deploy' After='SetDeployParams'>NOT Installed AND NOT PATCH</Custom>
      
        <Custom Action='SetRollbackParams' Before='RollbackDeploy'>NOT Installed AND NOT PATCH</Custom>
        <Custom Action='RollbackDeploy' Before='Deploy'>NOT Installed AND NOT PATCH</Custom>
      
        <Custom Action='SetUpgradeParams' After='InstallFiles'>Installed AND UPGRADEFOUND</Custom>
        <Custom Action='Upgrade' After='SetUpgradeParams'>Installed AND UPGRADEFOUND</Custom>
      
        <Custom Action='SetRepairParams' After='InstallFiles'>Installed AND NOT REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>
        <Custom Action='Repair' After='SetRepairParams'>Installed AND NOT REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>
      
        <Custom Action='SetUnDeployParams' After='MsiUnpublishAssemblies'>Installed AND REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>
        <Custom Action='UnDeploy' After='SetUnDeployParams'>Installed AND REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>
      
        <Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
      
      </InstallExecuteSequence>
      

      【讨论】:

        【解决方案4】:

        您需要保持升级代码不变并更改产品代码(如果您想要升级)。

        在 InstallExecuteSequence 中,您需要以下行

        <RemoveExistingProducts After="InstallInitialize" />
        

        在本例中,我选择将操作放在 installInitialize 序列之后,但是您可以将它们放在其他位置,这会给您带来不同的效果。

        This is a good reference

        【讨论】:

        • 感谢您的回复。但是,我确实尝试了您的建议。我保留了相同的 UpgradeCode,更改了产品和包代码。但是每次我运行新的 msi 时,都会提示我执行新产品的新安装。似乎 Windows 安装程序假定这是要安装的另一个产品,而不是现有产品的升级。
        • 对不起,我原来写的有错误,每次构建msi时都应该留下包代码,你会自动获得一个新的包代码,产品代码只能在你需要时更改升级。
        • 能否提供完整的源代码,以及安装日志。
        • 感谢您的快速回复。我之前浏览过 Alex 的博客,我什至更改了代码来实现它,但它仍然给出了我之前提到的相同错误。安装日志只显示初始包的安装成功,但没有关于升级的信息。我将在另一条消息中附上源代码。
        猜你喜欢
        • 1970-01-01
        • 2017-12-27
        • 1970-01-01
        • 2015-02-20
        • 2012-04-18
        • 1970-01-01
        • 1970-01-01
        • 2018-06-21
        • 2012-03-17
        相关资源
        最近更新 更多