【问题标题】:WiX overwrites config files during setup. How can I avoid this?WiX 在安装过程中会覆盖配置文件。我怎样才能避免这种情况?
【发布时间】:2011-01-27 08:27:08
【问题描述】:

我正在使用 WiX 创建 Windows 安装程序。不幸的是,我的安装程序在每次更新时都会覆盖一个配置文件。 我真正想要的是,安装程序仅在找不到文件时才创建文件。

感谢和问候, 叉子

【问题讨论】:

    标签: installation wix windows-installer configuration-files


    【解决方案1】:

    Component @NeverOverwrite="yes" 属性可能是解决此问题的方法。

    来自 WiX 帮助文档:

    如果此属性设置为“是”,则如果组件的密钥路径文件或密钥路径注册表项已存在,安装程序不会安装或重新安装该组件。应用程序确实将自己注册为组件的客户端。此标志仅用于由 Registry 表注册的组件。不要将此标志用于由 AppId、Class、Extension、ProgId、MIME 和 Verb 表注册的组件。

    Component Element Documentation

    【讨论】:

    • 嗯,这似乎是解决上述问题的方法,假设不能更改应用程序,只需安装程序...
    • 我不知道把配置文件变成它自己的组件有多么重要,或者注册表限制是否重要。
    • 最好的做法是让每个文件都成为它自己的组件。 stackoverflow.com/questions/1602831/…
    • @Simon 你的配置文件是它自己组件的keypath吗?它有稳定的向导吗?
    • @Dave Andersen:我相信,该文件将被 InstallExecuteSequence > RemoveExistingProducts 删除,这是一个强制元素。我想知道,关于 22 个赞成票,因为它显然不起作用。
    【解决方案2】:

    Component/@NeverOverwrite="yes" 会这样做。请记住在一个或多个文件上设置File/@KeyPath="yes",以便它可以检测它是否已经存在。

    如果您使用 heat.exe 自动收集文件列表,您可以使用以下 XSLT 样式表在每个包含配置文件的组件上设置此属性(并将每个配置文件元素设置为关键路径)。

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" 
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                    xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
                    exclude-result-prefixes="msxsl wix">
      <xsl:output method="xml" indent="yes" />
    
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="//*[local-name()='Component']">
        <wix:Component Id="{@Id}" Directory="{@Directory}" Guid="{@Guid}">
          <xsl:if test="contains(*[local-name()='File']/@Source, '.config')">
            <xsl:attribute name="NeverOverwrite">yes</xsl:attribute>
          </xsl:if>
          <xsl:apply-templates select="@* | node()"/>
        </wix:Component>
      </xsl:template>
    
      <xsl:template match="@KeyPath">
        <xsl:choose>
          <xsl:when test="contains(parent::node()/@Source, '.config')">
            <xsl:attribute name="KeyPath">
              <xsl:value-of select="'yes'"/>
            </xsl:attribute>
          </xsl:when>
        </xsl:choose>
      </xsl:template>
    </xsl:stylesheet>
    

    (注意:XML 命名空间处理可能会被清理,但它可以工作。)

    【讨论】:

      【解决方案3】:

      这确实是一个应用程序错误,而不是设置问题。

      您不应该“安装”用户以后可编辑的数据,Windows Installer 会记录已安装文件的大小、修改日期和哈希值。这样,如果以后发现文件“损坏”,就可以修复它。

      我们安装一个默认的配置文件,当没有找到时复制到用户配置中,这样 Windows Installer 甚至永远不会知道用户可编辑的配置,因此不会进行任何替换。

      【讨论】:

      • 正如我在上面写的 - 不幸的是我无法修复应用程序。
      • 安装时配置的配置文件怎么样。例如,具有安装特定连接字符串的 app.config 或 web.config。如果安装后需要更改此连接字符串怎么办?
      【解决方案4】:

      您可以使用REINSTALLMODE property 更改默认行为。它默认为“如果文件丢失或为旧版本,请重新安装”,这在逻辑上是正确的,对我来说。但是您可以尝试使用其他值来找到您需要的行为。

      希望这会有所帮助。

      【讨论】:

      • REINSTALLMODE 似乎是一个全局属性。我只想保存一个文件。
      【解决方案5】:

      我相信有人会想出一个正确的答案,但作为备份:

      如果正常配置文件不存在,您可以让安装程序创建一个默认配置文件,然后让您的应用程序将默认文件复制到正常配置文件中。这也提供了一种将应用程序重置为出厂默认设置的简单方法(只需删除配置文件)。

      【讨论】:

      • 好主意。但这在我的场景中不起作用 - 我无法更改应用代码。
      • 看来你接受了错误的答案,伙计 :) 下面的 Dave Andersen 为你的情况提出了一个很好的解决方法。
      猜你喜欢
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 2011-12-28
      相关资源
      最近更新 更多