You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wix:如何用XSLT阻止卸载时删除指定目录

解决MSI卸载/升级时保留整个Documents目录的问题

这个场景我太熟悉了——直接给Directory元素加NeverOverwrite和Permanent属性确实行不通,因为MSI的这两个属性本质上是绑定到File元素的,目录本身并不被MSI的安装引擎直接跟踪管理。下面给你几个靠谱的解决方案:

方案1:修改XSLT匹配Documents目录下的所有文件

核心思路是找到属于Documents目录的所有File元素,给它们逐一添加NeverOverwrite="yes"和Permanent="yes"属性。因为MSI只会删除它自己跟踪的文件,只要标记了这些属性,卸载时就会保留文件,升级时也不会覆盖。

示例XSLT代码:

<!-- 先获取Documents目录的唯一ID -->
<xsl:variable name="documentsDirId" select="*[local-name()='Directory'][@Name='Documents']/@Id" />

<!-- 匹配所有隶属于该目录的File元素 -->
<xsl:if test="*[local-name()='File']/@Directory=$documentsDirId">
  <xsl:attribute name="NeverOverwrite">yes</xsl:attribute>
  <xsl:attribute name="Permanent">yes</xsl:attribute>
</xsl:if>

如果Documents目录下还有子目录,你可以把匹配条件改成更宽泛的形式(前提是目录ID命名包含"Documents",比如INSTALLDIR_Documents_SubDir):

<xsl:if test="contains(*[local-name()='File']/@Directory, 'Documents')">
  <xsl:attribute name="NeverOverwrite">yes</xsl:attribute>
  <xsl:attribute name="Permanent">yes</xsl:attribute>
</xsl:if>

方案2:调整组件结构(适合WiX等构建工具)

如果你是用WiX构建MSI,可以把Documents目录下的所有文件单独放到一个组件里,然后给这个组件设置Permanent="yes"和NeverOverwrite="yes"属性。不过你提到这些文件是打包形式而非独立组件,这个方案可能不太适用,但可以作为备选思路。

注意事项

  • 确保你的XSLT是在正确的阶段应用:比如用WiX的heat工具生成文件列表时,要把这个XSLT作为转换参数传入,才能正确修改生成的WXS文件中的File元素。
  • Permanent="yes"会让文件在完全卸载时也保留,如果你只是想在升级时保留、卸载时删除,可以只设置NeverOverwrite="yes",去掉Permanent属性。

内容的提问来源于stack exchange,提问作者Sjharrison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:21:29