1

Is it possible to exclude a specific file name with Wix using transforms? I can exclude files that contain a certain string, but this excludes any file name matching the string. For example I can exclude file.exe with the following;

<xsl:key name="fileexe-search" match="wix:Component[contains(wix:File/@Source, 'file.exe')]" use="@Id"/>

but this will also exclude files with file.exe in their name, like file.exe.config.

Thanks.

neilwheeler
  • 23
  • 1
  • 4

2 Answers2

2

Looks like you should use ends-with instead of contains. But ends-with does not exist in XSLT 1.0. :)

This answer gives enough details to get the idea of how to implement it. Basically it is a combination of substring and string-length functions.

Besides, you should also consider normalizing the casing before comparison. That is, it is better to lower-case (or upper-case) both strings - the original and the one it ends with. This post can give you an idea of how to do it.

Keeping all this in mind, you will end up with something similar to this:

<!-- The starting backslash is there to filter out files like 'abcfile.exe' -->
<!-- Besides, it's lower-cased to ease comparison -->
<xsl:variable name="FileName">\file.exe</xsl:variable>
<xsl:variable name="ABC">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:variable name="abc">abcdefghijklmnopqrstuvwxyz</xsl:variable>

<xsl:key name="fileexe-search" match="wix:Component[translate(substring(wix:File/@Source, string-length(wix:File/@Source) - string-length($FileName) + 1), $ABC, $abc) = $FileName]" use="@Id"/>
Community
  • 1
  • 1
Yan Sklyarenko
  • 31,557
  • 24
  • 104
  • 139
  • You answer set me on the right path. For some reason whenever I used a variable I got an error; `heat.exe : error HEAT5055 : Error applying transform exclude.xsl to harvested WiX: Variables cannot be used within this expression.` So I replaced the variable with the actual filename. For my exclusion I am guaranteed the case of the filename so I didn't implement the case comparison. `` – neilwheeler Sep 28 '15 at 13:46
1

Although the answer provided by @Yan works I prefer to use C# which is simpler to use.

<xsl:stylesheet version="1.0"
    ...
    xmlns:my="urn:my-installer">
    ...

<msxsl:script language="C#" implements-prefix="my">
<msxsl:using namespace="System.IO" />
<![CDATA[
public bool EndsWith(string str, string end)
{
  if (string.IsNullOrEmpty(str))
    return false;

  if (string.IsNullOrEmpty(end))
    return false;

  return str.EndsWith(end);
}
]]>
</msxsl:script> 

    ...

Usage example:

<xsl:key name="ignored-components-search" match="wix:Component[my:EndsWith(wix:File/@Source, '.pssym')                                                   
                                               or my:EndsWith(wix:File/@Source, '.pdb')
                                               or my:EndsWith(wix:File/@Source, '.cs')
                                               or my:EndsWith(wix:File/@Source,'.xml')                                                      
                                                 ]" use="@Id" />
derwasp
  • 802
  • 8
  • 17
  • thanks @derwasp, I went with @Yan's answer as I couldn't figure out how to enable script execution using heat. I kept getting `heat.exe : error HEAT5055 : Error applying transform exclude.xsl to harvested WiX: Execution of scripts was prohibited. Use the XsltSettings.EnableScript property to enable it. `. I'm sure this would have worked just fine if I could have figured that out. – neilwheeler Sep 28 '15 at 13:53