【问题标题】:Components uninstalled during major upgrade重大升级期间卸载的组件
【发布时间】:2014-05-18 16:02:58
【问题描述】:

我有一个支持主要升级的 WiX 安装程序。我发现在某些特定的测试环境中,升级时的安装程序会删除现有未更改的组件。

这些(IIS web应用程序池、IIS网站等)组件都是这样安装的,在TARGETDIR下:

<Directory Id="TARGETDIR" Name="SourceDir">
      <Component Id="myComponent" Guid="MY-GUID">
        <iis:WebAppPool Id="ID" Name="MyWebAppPool" Identity="networkService" ManagedPipelineMode="classic" ManagedRuntimeVersion="v4.0"/>
      </Component>
</Directory>

对于有问题的环境,升级时会删除应用程序池。 以这种方式编写升级:

<MajorUpgrade Schedule="afterInstallExecute" DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."  AllowDowngrades ="no" />

在升级日志中,我看到以下条目:

MSI (s) (58:20) [11:22:58:433]:允许卸载共享 组件:{MY-GUID}。其他客户 存在,但安装到不同的位置

在未发现问题的环境中(即升级时未卸载组件),我看到以下日志条目:

MSI12cb8.LOG:9594:MSI (s) (10:EC) [09:36:37:068]:不允许 组件卸载:{MY-GUID} 因为另一个客户存在

我能想到的唯一解释是,对于问题环境,TARGETDIR 在初始安装和升级之间发生了变化。 According to RobTARGETDIR 设置为最大驱动器。如果系统上最大的驱动器(可用空间最多的驱动器?)在初始安装和升级之间发生变化,则组件的密钥路径将发生变化,从而导致组件在升级时被卸载。

问题

  • 这个解释听起来正确吗?
  • 如何解决此问题以升级现有产品安装?有没有办法在升级时将TARGETDIR 设置为与初始安装相同的值?

【问题讨论】:

    标签: iis wix installation windows-installer


    【解决方案1】:

    发生的事情似乎是这样的:您的升级安装到某个您似乎在说您几乎无法控制的 TARGETDIR。在升级结束时,RemoveExistingProducts 卸载旧产品,这包括删除应用程序池,因为正在卸载组件,可能是通过自定义操作(因为没有对应用程序池的本机支持)。从旧位置删除组件很好,因为那里不再需要它,但看起来删除应用程序池的自定义操作与该组件删除相关联,因此删除了应用程序池。换句话说,您已将您的应用程序池绑定到现在要求您进行就地升级的组件共享规则。另一种看待它的方式是,在这样的情况下,人们在 CA 上的卸载条件中添加“AND NOT UPGRADINGPRODUCTCODE”以删除应用程序池,这样它就不会在升级时删除应用程序池,因为它可能只是与您的情况一样,已在新位置创建。

    这有点啰嗦,抱歉,但是就地升级的要求通常可以通过在系统上有一些您可以搜索的内容(例如注册表项)并将安装文件夹设置到该位置来满足,不允许任何可以改变它的用户界面。您还应该开始控制您的安装文件夹(您听起来好像您的安装可以在任何地方进行)。这里的关键词是“默认”。如果您懒得设置 TARGETDIR ,它将默认在某个地方。

    【讨论】:

    • 感谢@PhilDW。我正在使用WiX IIS extension 安装应用程序池。请注意,所有实际文件都由我的安装程序安装到我可以控制的正确 %PROGRAMFILES% 文件夹中。在默认的TARGETDIR 下仅安装了诸如 IIS 应用程序池之类的组件。对于将来的升级,我还可以确保将TARGETDIR 设置为一致的目录。我试过“NOT UPGRADINGPRODUCTCODE”条件,但这似乎并没有解决问题。将对此进行更多实验。
    • 顺便说一句,明确设置TARGETDIR 是常见的做法吗?我没有创建安装程序脚本,但我希望它最初是由查看the WiX tutorial 的开发人员编写的,似乎没有提到明确设置TARGETDIR
    • 通常有类似 CustomAction Id="SetInstallDir" Property="INSTALLDIR" Value="[ProgramFilesFolder][Manufacturer][ProductName]" 和调用自定义操作以确保它在UI 序列和执行序列(在静默安装的情况下)。然后,INSTALLDIR 属性就是 UI 显示(并且可能更新)的内容,允许用户更改它,以 INSTALLDIR 为例。
    • P.S.请记住,NOT UPGRADINGCODE 在较旧的安装中,因此如果您已经发布了它,那么为时已晚。我不会在升级安装中工作。
    【解决方案2】:

    对于遇到类似问题的其他人,我使用自定义操作解决了它。正如@PhilDW 指出的那样,NOT UGPRADINGPRODUCTCODE 不适用于现有安装。我想不出在升级时停止删除应用程序池的方法。相反,我添加了一个为删除之后安排的自定义操作,如果应用程序池被删除,它会重新添加它。

    <CustomAction Id="CreateAppPoolCustomAction.SetProperty" Return="check" Property="CreateAppPoolCustomAction" Value="AppPoolName=$(var.AppPoolName)" />
    <CustomAction Id="CreateAppPoolCustomAction" BinaryKey="MyCustomActions.CA.dll" DllEntry="CreateAppPoolCustomAction" Execute="deferred" Return="check" Impersonate="no" />
    
    <InstallExecuteSequence>
      <Custom Action="CreateAppPoolCustomAction.SetProperty" Before="CreateAppPoolCustomAction" />
      <Custom Action="CreateAppPoolCustomAction" After="RemoveExistingProducts">WIX_UPGRADE_DETECTED AND NOT (REMOVE="ALL")</Custom>
    </InstallExecuteSequence>
    

    MyCustomActions.dll 中的 C# 自定义操作使用Microsoft.Web.Administration.ServerManager 创建应用程序池(如果缺少)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 2015-04-06
      • 2015-11-15
      • 2019-01-04
      相关资源
      最近更新 更多