Search code examples
wixinstallationwindows-installerheat

Using heat.exe for files placed in WindowsVolume - GUID Issues


I searched some time on SO and Google but I didn't find related questions. So hopefully this issue isn't a duplicate.

For a customer of mine I'm creating installer artifacts with WiX. Some files are installed to

[WindowsVolume]\tool\scripts. 

That went fine as long as I manually added those files to the according WiX fragment. Since files of this component are being moved and removed pretty often lately I decided to fetch them via heat.exe from subversion. A problem I'm facing is, that heat's -ag switch refuses to work on [WindowsVolume] - I guess because -ag keeps the GUIDs static as long as the path to the Component's directory stays the same. Therefore I used -gg to generate new GUIDs during each run of heat. Testers are now reporting that files weren't replaced and the folder doesn't get created at all sometimes.

Using autogenerated GUIDs by setting -ag switch I get the following error message from light:

C:\checkouts\project\Setup\tool.fragment.wxs(41,0): error LGHT0231: 
The component 'cmpF69984FE7B4A36DD402E57B30E416ACB' has a key file with path 
'TARGETDIR\indexes\arbitrary.file'.  Since this path is not rooted in one of 
the standard directories (like ProgramFilesFolder), this component does not 
fit the criteria for having an automatically generated guid.  (This error may 
also occur if a path contains a likely standard directory such as nesting a 
directory with name "Common Files" under ProgramFilesFolder.)

In WiX I've got a main .wxs defining folders, features and the InstallExecuteSequence. The relevant folder definition is:

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ToolFolder">
    <Directory Id="ToolScriptsFolder" Name="scripts"/>
  </Directory>
</Directory>

<SetDirectory Id="ToolFolder" Value="[WindowsVolume]tool" />

The harvested Fragments are:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <DirectoryRef Id="ToolScriptsFolder" />
  </Fragment>

  <Fragment>
    <ComponentGroup Id="CG_ToolScripts">
        <Component Id="cmp2BCA6A75C5C234BEF6FAD9FC41C4B661" 
                   Directory="ToolScriptsFolder" Guid="*">
            <File Id="fil8C1ADEFF76E859B93A97C72A95365E90" 
                  KeyPath="yes" Source="$(var.ToolScripts)\arbitrary.file" />
        </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

Any idea how to get automatic generated GUIDs working without moving tools\scripts to [ProgramFiles]? Any help that relieves me from manually editing the fragment is appreciated :) Thanks in advance!


Solution

  • Since I didn't find a solution for this I implemented a workaround. Just in case anyone stumbles upon a similar issue in the future, here's what did the trick:

    1. checking registry for the scripts' directory installed by a prior installation
    2. adding a RemoveFolderEx custom action to remove the directory written to registry during a prior installation
    3. writing the scripts' directory to registry for further use during the next installation

    In code it looks somewhat like:

    <Property Id="LAST_KNOWN_SCRIPTS_LOCATION">
      <RegistrySearch Key="SOFTWARE\vendor\product" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="scriptsLocation" />
    </Property>
    
    <SetProperty Id="LAST_KNOWN_SCRIPTS_LOCATION" Value="some\default\directory" Before="AppSearch"><![CDATA[LAST_KNOWN_SCRIPTS_LOCATION]]></SetProperty>
    
    <DirectoryRef Id="ToolScriptsFolder">
      <Component Id="cmp2EB940FB7EFA4691AD58C7AE293A529E" Guid="ED4252705A824BD19441C5574CC99E67">
        <RegistryValue Root="HKLM" Key="SOFTWARE\vendor\product\scriptsLocation" Value="[ToolScriptsFolder]" Type="string" KeyPath="yes"/>
        <util:RemoveFolderEx Id="rmfx_ScriptsFolder" On="both" Property="LAST_KNOWN_SCRIPTS_LOCATION"/>
      </Component>
    </DirectoryRef>