Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WiX overwrites config files during setup. How can I avoid this?

Tags:

I'm using WiX to create a windows installer. Unfortunately my installer overwrites a config file on every update. What I really want is, that the installer only creates the file if it is not found.

Thanks and regards, forki

like image 855
forki23 Avatar asked Mar 14 '10 08:03

forki23


2 Answers

The Component @NeverOverwrite="yes" attribute might be the solution to this problem.

From the WiX help documentation:

If this attribute is set to 'yes', the installer does not install or reinstall the component if a key path file or a key path registry entry for the component already exists. The application does register itself as a client of the component. Use this flag only for components that are being registered by the Registry table. Do not use this flag for components registered by the AppId, Class, Extension, ProgId, MIME, and Verb tables.

Component Element Documentation

like image 123
Dave Andersen Avatar answered Oct 17 '22 05:10

Dave Andersen


Component/@NeverOverwrite="yes" will do this. Just remember to set File/@KeyPath="yes" on one or more of the files so it can detect whether it is already present.

If you're using heat.exe to harvest your file list automatically, you can use the following XSLT stylesheet to set this attribute on each Component containing a config file (and set each config File element as a key path).

<?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> 

(Note: the XML namespace handling can probably be cleaned up, but it works.)

like image 37
Richard Dingwall Avatar answered Oct 17 '22 04:10

Richard Dingwall