WiX Relative Path to the Source File - wix

I have a simple Solution for my Project, which works well. But I am unable to grasp how to make the Source paths relative. Can somebody help me?
<Component Id="Bla.exe" Guid="*">
<File Id="Bla.exe" Source="D:\Projects\Bla\Bla\bin\Debug\Bla.exe" KeyPath="yes" Checksum="yes"/>
</Component>
How can I make the Path relative to the Wix Solution? WiX and all necessary files are in the same Solution.

You can use the relative path like so:
<File Id="Bla.exe" Source="..\bin\Debug\Bla.exe" KeyPath="yes" Checksum="yes"/>
OR
You can add a configuration file to your project to define common variables. To do so, add a new "WiX Include" file to your project, call it config.wxi. Then in your include file, you can define a SourceDir variable like so:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define SourceDir = "D:\Projects\Bla\Bla\bin\Debug" ?>
</Include>
Now in your .wxs file, you can add a reference to the config file at the top, ex:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include "config.wxi"?>
Then just reference your SourceDir variable like so:
<File Id="Bla.exe" Source="$(var.SourceDir)\Bla.exe" KeyPath="yes" Checksum="yes"/>
Also, there are some built in WiX project variables that you may use.

There are many ways to do this but personally what I like to do is put my application installer projects in different solutions. I build the application solution first and use postbuild commands to publish the content to a deploy folder.
In my installer projects I set $(var.SourceDir)="..\deploy" and then $(var.SourceDir)\foo.exe for a source path.

Related

Wixtoolset, specifying source to a file based on where the installer is

How do I specify the source of a file based on where the installer I am running is located. Say for example that I want to place a few files from the folder of the installer(that is for instance located on the desktop or in downloaded files) into a specified path in C/programfiles.
<ComponentGroup Id="ProgramFilesFolder_files" Directory="INSTALLFOLDER">
<Component Id="Program.exe" Guid="d0c868d9-4d5b-41f0-9ce8-d655ac80ee7c">
<File Id="Program.exe" Name="Program.exe" Source="???" />
How do I set the source property?
Have i understood it right that I am supposed to set the source to:
Source="..\Program.exe"
Does this refer to where the MSI file is run from. If I for example put my installer file along with the files I need the source for. Will I be able to use the code above as a relative path that changes when I move the installer. So I can run the installer from elsewhere, with the only requierment that the installer is in the same folder as the files I want to program the source for?
I have an open source project that makes authoring WiX installers easier. One of it's features is relative file paths. You can read about it here.
https://github.com/iswix-llc/iswix-tutorials
Essentially the project templates use an XPI called SourceDir to create an abstraction for where to find the source files. This is relative to the WXS file. The GUI tool uses the location of the WXS and the SourceDir to enumerate the source structure for drag / drop operations and then uses it to author the File elements like such.
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ComponentRules="OneToOne"?>
<!-- SourceDir instructs IsWiX the location of the directory that contains files for this merge module -->
<?define SourceDir="..\Deploy"?>
<Module Id="DesktopApplicationMM" Language="1033" Version="1.0.0.0">
<Package Id="04cfbb1b-8105-4f3e-9b7a-c1d5354dc670" Manufacturer="DesktopApplicationMM" InstallerVersion="200" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" />
<Directory Id="MergeRedirectFolder">
<Component Id="owc17DECDE7A34AF545285829FF09EF24AE" Guid="4791fdfe-28ff-3c07-2f9e-e2f418c712f8">
<File Id="owf17DECDE7A34AF545285829FF09EF24AE" Source="$(var.SourceDir)\DesktopApplication.exe" KeyPath="yes">
<Shortcut Id="sc06A337B51AED2DF7E22F894A213D2792" Name="Desktop Application" Directory="DesktopFolder" />
</File>
</Component>
</Directory>
</Directory>
<ComponentGroupRef Id="Custom" />
</Module>
</Wix>
If you ever refactor where the files come from you only have one line to update.

Wix : error LGHT0204 : ICE80: This 32BitComponent xxx uses 64BitDirectory yyy

I want to create an installer (msi) for my application. I want to add a folder that contains lot of files. So I use heat to create the wxs file for the folder. The wxs file created looks like this :
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLDIR">
<Directory Id="dirD443000E4EC0AE53948090C1CD372519" Name="www">
<Component Id="cmp258C40B6C01189153117075B9889DA7C" Guid="{23189859-29AE-46E6-A940-0B2307344910}">
<File Id="fil0DE52257C6EF99D33B0974915A17454E" KeyPath="yes" Source="$(var.WwwPath)\3rdpartylicenses.txt" />
</Component>
<Component Id="cmp85367E8DB342884A004620F1E4153AE4" Guid="{00EBB07A-6178-4072-B47C-2D9130CB96A7}">
<File Id="filB62696889B5411543CB3DFD6E2A1270D" KeyPath="yes" Source="$(var.WwwPath)\color.c7a33805ffda0d32bd2a.png" />
</Component>
...
...
When I run my command light, I get a lot of error like this one (one per file):
error LGHT0204 : ICE80: This 32BitComponent cmp258C40B6C01189153117075B9889DA7C uses 64BitDirectory dirD443000E4EC0AE53948090C1CD372519
But the msi created seems to work as expected. But I would like to understand and remove that error if I could.
Any idea ?
Thanks
I've tried adding componnents atrributes Win64='yes' like in #Brian's comment, but it removed during build.
This answer helped me solve this issue.

WiX Heat tool cannot harvest info from executables

Can anyone confirm that heat works only on DLLs, OCX, maybe some other files, but not on executable files?
The thing is, that I run heat on my COM components DLLs or OCXs (registered through regasm, regsvr32) and it harvests all data in the registry related to the file. However, I have DCOM servers that have lots of info related to themselves in the registry (self registered using /regserver) and the harvesting tool extracts just a minimal information about the file itself but nothing from registry related to the file, NOTHING. Like the resulted wxs file could be something like this:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="ohserver.exe" Guid="{E8D87743-45B6-459E-A72F-22D9A0D5CE16}">
<File Id="ohserver.exe" KeyPath="yes" Source="SourceDir\ohserver.exe" />
</Component>
</DirectoryRef>
</Fragment>
</Wix>
As you see nothing from registry, CLSIDs, ProgIDs, RegistryValues, etc.
That's correct. Heat does not support harvest self-reg data from .exe servers.

How can I remove a folder located in the same folder of my setup after installation in Wix?

I am trying to make a setup file for an application with Wix. After the installation of the program the setup should remove a folder located in its same folder. I don't know how to do it. All I know is that I have to use the RemoveFolder element, that must be placed inside a Component element. So far I have written this but it doesn't work.
<Component Directory="CURRENTDIR" Id="cd1">
<RemoveFolder Id="rf1" On="install" Directory="NameOfFolderToRemove"/>
</Component>
Take a look at util:RemoveFolderEx
http://wixtoolset.org/documentation/manual/v3/xsd/util/removefolderex.html
You will need to reference WixUtilExtension in your project and include
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
in your Wix tag like below:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<RemoveFolder> will only remove empty folders so if there are files in the folder the remove folder action won't work.

Wix: Merge Module with multiple wxs files

So, I am trying to create a merge module where I have multiple wxs files. I thought that everything was OK since the build of my project succeeded. Later, I realized that the path used in Source attribute for one of the secondary wxs files was completely wrong but the compiler didn't give the following error:
The system cannot find the file '..\..\release_area\WrongPath\Component2.dll'.
In the secondary wxs file, I added a DirectoryRef element referencing the folder AssemblyFolder in the main wxs file to create the reference between the two files.
Main wxs file:
<Module Id="MyModule" Language="1033" Version="1.0.0.0">
<Package InstallerVersion="200" Platform="x86"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="AssemblyFolder">
<Component Id="Component1.dll">
<File Id="Component1.dll" Name="Component1.dll"
KeyPath="yes" Assembly=".net"
Source="..\..\release_area\Comp\Component1.dll" />
</Component>
</Directory>
</Directory>
</Module>
Secondary wxs file:
<Fragment>
<DirectoryRef Id="AssemblyFolder">
<Component Id="Component2.dll">
<File Id="Component2.dll" Name="Component2.dll"
KeyPath="yes" Assembly=".net"
Source="..\..\release_area\WrongPath\Component2.dll" />
</Component>
</DirectoryRef>
</Fragment>
Just to clarify: To test, I copied my <Component Id="Component2.dll"> directly in the main wxs and I got the error: The system cannot find the file '..\..\release_area\WrongPath\Component2.dll'.
So, my guess is that the reference between the secondary wxs file and the main wxs file is completely wrong and that's why the compiler doesn't validate the file path but I cannot figure out what is the problem.
The issue isn't in the compiler (candle.exe). Candle.exe creates the separate "sections" (Module and Fragment are both "sections"). It is the linker (light.exe) that is responsible for pulling it all together. Light.exe starts at the "entry section" (Product, Module or Patch) and follows the references down from there. Since you don't have a reference from your Main.wxs to your Secondary.wxs, the stuff in the Secondary.wxs is never pulled in. To resolve this just add:
<ComponentRef Id="Component2.dll"/>
somewhere under your Module element (I usually put them at the end). If you get lots of Components then ComponentGroup and ComponentGroupRef becomes useful.