Creating Files and Directories with WiX
Overview
You can create files and directories in the .wxs source. <sarcasm>I know, this sounds like a real novelty feature for an installer, but what till you see the great syntax used!</sarcasm>.
One of the fundamental ideas in WiX is this:
- Your project consists of one or more (typically many more) logical
Components
. Components
are grouped inDirectories
- Each
Component
consists of one or moreFiles
(typically, a single file). - A
Feature
is a group ofComponents
installed together. Many MSIs have a singleFeature
, "Install Everything", that consists of allComponents
Does that make sense? Let's talk about directories first
Directories
There are a couple of rules that you need to follow:
- The root directory has a special Id
TARGETDIR
and is not actually a directory. - Under that comes the first "real" directory, which is typically something like %ProgramFiles%. They are specified with special Ids as well, which are documented on MSDN
- Under that comes your very own directory / directories
Let's look at the basic structure:
<?xml version='1.0' encoding='utf-8'?>
<Wix ...
<Product Name='blablabla' ...
<Package Id='*' ...
<Media Id='1' ...
<Property Id='DiskPrompt' ...
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='INSTALLDIR' Name='NAME OF YOUR PROGRAM GOES HERE'
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
Files
As mentioned above, you need to decide whether you group multiple files in one component, or have a single component for each file. Feedback is undecisive, but it seems perfectly normal to actually go ahead and do create a single component for every single file you have, so that is what I do, too. Example:
... (inside a <Directory>) ...
<Component Id='bin_foo_dll' Guid='YET ANOTHER GUID GOES HERE'>
<File Id='bin_foo_dll_file' Name='foo.dll' DiskId='1' Source='BIN\foo.dll' Vital='yes'/>
</Component>
<Component Id='bin_bar_dll' Guid='YET ANOTHER GUID GOES HERE'>
<File Id='bin_bar_dll_file' Name='bar.dll' DiskId='1' Source='BIN\bar.dll' Vital='yes'/>
</Component>
<Component Id='bin_blub_dll' Guid='YET ANOTHER GUID GOES HERE'>
<File Id='bin_blub_dll_file' Name='blub.dll' DiskId='1' Source='BIN\blub.dll' Vital='yes'/>
</Component>
... (more files here) ...
This is a shining example of the sort of repetitive idiocy common in WiX files. This is especially a problem if you need to convert an existing project to WiX: You need to create all this structure (I wrote a Python script, but that is heavily tuned to the needs of my particular project, so your mileage may vary...).<
Note that both Component
and File
must have Ids
, and they must be unique.
(And you need a ****** DiskId
, for good riddance!). Did I mention repetitive idiocy?
BTW, Vital='yes'
means that installation will fail if the file cannot be installed. You can guess what Vital='no'
does...
Features
Your project needs at least "one feature". Typically, the feature is "everything", but you can think of instances where the feature actually
installs lots of different things instead. At any rate, the Feature
must be declared after the last </Directory
and
looks something like this:
... (files and directories here) ...
<Feature Id='Complete' Level='1'>
...
<ComponentRef Id='bin_foo_dll'/>
<ComponentRef Id='bin_bar_dll'/>
<ComponentRef Id='bin_blub_dll'/>
...
GK, Jan 28, 2014