Search code examples
msbuildwixheat

Harvesting multiple files with one C# COM dll


I'm compiling a WiX installer and using Heat to harvest my files but I'm running into a problem where I have a directory I'm harvesting that contains 1 C# COM dll. I need to basically run regasm on this. I have the following in my wix project file to harvest the files:

<HeatDirectory OutputFile="%(ProjectReference.Filename).wxs" 
               Directory="..\ExactaMobilePublish\" 
               DirectoryRefId="INSTALLFOLDER" 
               ComponentGroupName="%(ProjectReference.Filename)" 
               SuppressUniqueIds="true" 
               SuppressCom="false" 
               SuppressFragments="true" 
               SuppressRegistry="false" 
               SuppressRootDirectory="true" 
               AutoGenerateGuids="false" 
               GenerateGuidsNow="true" 
               ToolPath="$(WixToolPath)" 
               PreprocessorVariable="var.BasePath" />

The problem I'm having is that while it is generating the necessary registry information for my C# COM dll it's also generating registry information for a bunch of other dlls in that folder that aren't exposed to COM.

Is there any way around this? Should I instead try harvesting that single C# COM dll into a separate wxs file?

Edit

I did try harvesting the single C# COM dll in a seperate WiX file in addition to the directory defined above but I got the expected error:

Error   5   Duplicate symbol 'Component:ExactaDatabaseAccess.dll' found. This typically means that an Id is duplicated. Check to make sure all your identifiers of a given type (File, Component, Feature) are unique.  C:\TFS\Covance\Dev\ExactaMobileCNA317\Installer\ExactaMobileInstaller\ExactaMobile.wxs  143 1   ExactaMobileInstaller

I could probably exclude this file from the directory above by using an xslt transform but this seems like overkill.


Solution

  • I ended up resolving this by doing as I had suggested in the edit above. I harvested the single file using HeatFile and excluded the file from the HeatDirectory harvest by using an xslt transform.

    I had the following in my project file:

    <HeatDirectory OutputFile="%(ProjectReference.Filename).wxs" 
                   Directory="..\ExactaMobilePublish\" 
                   DirectoryRefId="INSTALLFOLDER" 
                   Transforms="ExcludeExactaDatabaseAccess.xslt" 
                   ComponentGroupName="%(ProjectReference.Filename)" 
                   SuppressUniqueIds="true" 
                   SuppressCom="true" 
                   SuppressFragments="true" 
                   SuppressRegistry="true" 
                   SuppressRootDirectory="true" 
                   AutoGenerateGuids="false" 
                   GenerateGuidsNow="true" 
                   ToolPath="$(WixToolPath)" 
                   PreprocessorVariable="var.BasePath" />
    <HeatFile OutputFile="ExactaDatabaseAccess.wxs" 
              File="..\ExactaMobilePublish\bin\ExactaDatabaseAccess.dll" 
              DirectoryRefId="MOBILEBIN" 
              ComponentGroupName="ExactaDatabaseAccess" 
              SuppressUniqueIds="true" 
              SuppressCom="false" 
              SuppressFragments="true" 
              SuppressRegistry="false" 
              SuppressRootDirectory="true" 
              AutoGenerateGuids="false" 
              GenerateGuidsNow="true" 
              ToolPath="$(WixToolPath)" 
              PreprocessorVariable="var.ExactaMobileBinBasePath" />
    

    I used the following xslt transform:

    <?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" exclude-result-prefixes="msxsl"
          xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
    
      <!-- Copy all attributes and elements to the output. -->
      <xsl:template match="@*|*">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          <xsl:apply-templates select="*" />
        </xsl:copy>
      </xsl:template>
    
      <xsl:output method="xml" indent="yes" />
    
      <!-- Search directories for the components that will be removed. -->
      <xsl:key name="dll-search" match="wix:Component[@Id = 'ExactaDatabaseAccess.dll']" use="descendant::wix:File/@Id"/>
    
      <!-- Remove components. -->
      <xsl:template match="wix:Component[@Id='ExactaDatabaseAccess.dll']" />
    
      <!-- Remove componentsrefs referencing components in those directories. -->
      <xsl:template match="wix:ComponentRef[key('dll-search', @Id)]" />
    </xsl:stylesheet>