Can I create a component with Wix that has files in different directories/subdirectories? Or all the files of a component should be in the same directory?
How do I set the XML for that?
No.
See the Windows Installer documentation on Components... one of the main rules is that Each component must be stored in a single folder.
Component rules are very easy to violate, the best solution is to stick to one file per component if there is any chance at all any of the files will change in a later version.
Putting multiple files into a component can cause headaches down the line, avoid it if possible unless you have a valid reason - and having easier to maintain WiX sources isn't a valid reason :)
Related
I am someone with little to no experience with wix and I am trying to support Windows also for the component I am responsible for. I am trying to create merge module for a set of files that my product generates. These files exist in numerous sub directories. I was wondering how I can create a single component ID for all the files in the entire tree. I am not worried about minor upgrades as that is something I am not going to be doing. I am trying to avoid generating numerous GUIDs for each of the file.
Also is there any way I can change the name of the root directory I want the files to be installed. Currently, in our build system the files I want to install end up in a directory name "install". In the wxs file generated by heat it comes up as install. I was wondering if I could change it to the actual product name instead of "install".
Use one file per component - this avoids all sorts of problems (except .NET assemblies spanning multiple files). See the following thread: One file per component or several files per component?
Wix is a great framework for creating installers, but it has a steep learning curve. I strongly recommend you read a few sections of this great, online tutorial: https://www.firegiant.com/wix/tutorial/
If you are a "sample based tinkerer", you can find an even quicker, sample based tour in this article: http://www.codeproject.com/Tips/105638/A-quick-introduction-Create-an-MSI-installer-with
Wix is hands-on. Just focus on the samples, and focus on getting the components created and a major upgrade set up:
How to implement WiX installer upgrade? (modern, convenience way)
How to get WiX major upgrade working? (legacy way - more flexible, less convenient)
http://wixtoolset.org/documentation/manual/v3/howtos/updates/major_upgrade.html
Once you got that running the rest of the details fall into place by reading the documentation for whatever feature you need. Using Visual Studio / Votive with intellisense ensures that you can learn as you go with features such as shortcuts, ini files, xml files, dialogs, etc...
Another top tip is to use dark.exe (part of the Wix toolkit) to decompile existing MSI files. This yields Wix XML with code you can copy and paste into your own Wix files. I use other MSI tools to compile such MSI files, and then copy the sections I need into my Wix file - just to speed up the process of creating the Wix XML. Studying the decompiled XML is very educational - a real time saver.
UPDATE, May 2021: Some more links:
WiX Quick Start - Very long version
WiX Quick Start - Short version
If all the files are going to the same destination folder, then you can create one single COMPONENT with all the FILE within it. There is nothing stopping you to do that. You can then just create one GUID for that component. Also read these answers which talks about the advantages vs disadvantages of one component vs multiple components before you implement it: Answer1 Answer2. To Summarize:
You will have trouble with minor upgrades/repairs. If a component is
being updated, only the file designated as the KEYPATH is checked to see if
it is out of date: if it is up to date, all the others are ignored.
You'll also have difficulty if you want to add or remove files from each
component. Once released, a component is immutable (in terms of what files
are in it). The only way to update it without breaking component rules would
be to effectively remove and install the a new version of the MSI.
Understanding the component rules is key in Windows Installer and one file
per component makes the component rules easier to work with, which is why it
is the recommendation of many people here.
LINK
The root directory name can be changed by modifying the "Name" property for the DIRECTORY element.
Background:
I'm making a setup for an application with three Configurations/SKUs (Basic, Standard, Enterprise, say) and two platforms (x86, x64). The different configurations use different upgradecodes.
That gives you a matrix of six different configurations. We currently have separate wxs scripts for each configuration, but when a file is added by hand to the setup it's nearly impossible to remember to do correctly in all of them etc. Most of the files are shared (by name, not content) so there is a file SomeNamespace.SomeLibrary.dll in all six setup packages, but all six are potentially different (by platform and sometimes by Configuration as well).
So my first question is: how can I avoid having to keep several large but almost identical setup scripts?
Second issue: component ID's:
If I manage to re-use a lot of the wxs scripts through fragments created by a custom harvester or template, what do I do about Component ID's? Can I use the generated (*) GUIDs for my components, given that no component is shared between products, and I use MajorUpgrade only? The other option for component ID generation would be using heat, or manually making a deterministic hash such as SHA1(relative install path + configuration + platform)`.
Is there a good example somewhere of a large multi-configuration multi-platform WiX project?
Well, have you learned WHY it's good idea to have seperate component ID's for each file of your setup?
Here are links to understand what is going on:
What is the wix 'KeyPath' attribute?
Wix: one file per component or several files per component?
Wix: Using KeyPath on Components, Directories, Files, Registry, etc, etc
As for your question, I would say that it makes sense to have each file have it's own component identifier(and putting them to seperate products does not change that).
ComponentSearch doesn't even need ProductCode in order to search for specific component - think about what would happen if you have two Products installed and they both have same GUIDS for some Component - it's going to explode.
Is there any way to create a new text file and write to it using Wix? I have come across elements that will allow me to work with Xml files and Ini files, but nothing for a plain text file.
The root of the problem stems from the fact that we're using a third party library that reads from its own custom configuration file, which really ties my hands as to what the text file can look like. The configuration file is similar to an Ini file, minus the "sections." And I've noticed that Wix handles Ini files by always placing them in the system folder, which won't work for our needs.
The data that needs to be written to the configuration file is gathered at run-time, so there's no opportunity to simply lay down a pre-configured file.
I would be willing to accept a Wix extension to accomplish the same result if one exists, but haven't come across one yet.
There is no built-in feature in Windows Installer for this. You'll have to write code to do it and invoke that code with a custom action.
The IniFile element can write .ini files anywhere; use the #Directory attribute to specify which directory it should go in. If the library ignores [section] lines, you can use anything as the #Section attribute value.
You might want to have a look at this project. It contains the collection of WiX extensions and custom actions, and I suppose it also has CA to read and write text files. Try it out - it is claimed to be tested and proved by using in enterprise installations.
Visual Studio Installer states that it is a best practice to install each file as an installer component. The heat utility provided with Wix also seems to follow the practice of putting every file in its own component.
InstallShield's component wizard uses InstallShield's setup best practice of placing portable executable files in their own component but groups all other files (e.g. unversioned files) by the common destination folder.
The advantage of practice one (each file in its own component) is that each file is set up as a key file which is important if you want these files to trigger repairs. It also allows automation of creating the components (e.g. heat) easier since you are creating a component for each file.
The disadvantages of practice one include the overhead of managing so many components and the bloating of the registry after the application is installed.
An advantage of practice 2 could be seen in an install that installs hundreds of graphics files to one directory. If you do not care about repair functionality, is there any reason to create hundreds of components for this install?
These 2 different practices are conflicting and I want to know which one that people actually use and why.
I always use the Microsoft approach (something similar to what InstallShield does):
http://msdn.microsoft.com/en-us/library/aa368269(VS.85).aspx
I think it's the best because:
- important files (EXE, DLL etc.) have their own component, so they can be repaired easily
- resource files are grouped together
- it allows an optimum components count (not too many to get a long install, but enough to allow an easy repair)
I also noticed that most commercial setup authoring tools use this approach.
I've written about this in the past and I'll try to find a link to it. I think you already understand the question and it's just time for you to decide what is important to you.
For me, I work on installs with 15,000+ files and we only service with major upgrades. For "Program Executables" we follow 1:1 principals ( a must for COM, Services, ShortCuts and so on anyways ) but for content/data files we actually do a 1 to many with no key file approach to cut down on our number of components. Sure, that means we won't be able to create an MSP that services just one or two content files here and there but for our business needs that's simply not important to us.
Resilency was a bit of a 4 letter word to us so having less key files makes us happier anyways. :-) BTW, VDPROJ also makes every registry key a keyfile of it's own component and that was quite painful for us triggering unneeded repairs.
All of this aside, for anyone who doesn't fully understand all of this, I'd stick to the 1:1 pattern until you come across a situation where you don't want to anymore and you understand the impact of making that choice.
When should I change or not change my component GUID in WIX? The Microsoft SDK information is confusing.
Glytzhkof edit: To clarify, the question deals with when a component GUID should be changed for an MSI component. A component can change with aspects such as: changed destination path, addition or removal of files to/from the same component, addition of registry data etc... This causes problems with regards to the so called component referencing, i.e the best practice for creating components in MSI.
The overall concept of MSI is that there is a 1:1 mapping between
a component GUID (unique identifier) and an absolute path
(install location / key path). The full path, including file name if
any. See update below for a new Wix feature to deal auto-magically
with this.
Rob Mensching (WiX author):
Windows Installer Component Rules 101
Windows Installer Components Introduction
More on Component Rules:
Organizing Applications into Components
Best Practice for Creating Components.
I use some simple rules to deal with the overly complex and rather counterintuitive component rules (especially for developers as opposed to deployment specialists):
Always use a separate component per file (even for non-binaries). This avoids all kinds of problems. There are a few exceptions:
Multi-file .NET assemblies should all be in one component since they should always be installed / uninstalled as a single unit.
A few other, general file types come in "matching pairs" - they belong together. Often these are content and index files. As an example consider Microsoft help files:
.HLP and .CNT files belong together.
.CHM and .CHI files belong together.
There are likely several such file types that belong together and should hence be put in the same component so they install/uninstall together - I suspect certain certificate files to be candidates. It is hard to come up with a definite list. Simply ask yourself "do these files always belong together" - so they always show up in pairs whenever there is a new version? If yes, then install them via the same component. Set the versioned file, if any, as key file.
I want to add driver files as an example of a bunch of files always belonging together: SampleDriver.cat, SampleDriver.inf, SampleDriver.sys, SampleDriver.cer. They must all match as a "unit" for deployment.
Remember that once you have allocated a GUID for a component, it's set in stone for that component's key path (absolute path). If you move the file to a new location or rename the file, give it a new component GUID (since the absolute path is different it's effectively a new identity).
In summary component GUIDs are tied to an absolute installation location, and not to a specific file. The GUID doesn't follow the file around if it moves. The GUID reference counts an absolute location, not the file per se.
Do not add or remove files from an existing component. All sorts of upgrade and patching problems result. This is why I like one file per component as a general rule.
There is a lot more to component referencing, but I will leave it at that for an "overview".
Some samples:
You rename the file C:\Program Files\MyCompany\MyApp\MyFile.exe to C:\Program Files\MyCompany\MyApp\MyFile_NEW.exe. What does this mean for component creation? This is a new absolute installation path, so you generate a new GUID for the hosting component, OR you add a new component and delete the old one (which has the same effect).
Your updated MSI delivers a new version of MyFile.exe. The location is the same as before, this means the component GUID should not change. It is the same file (identity), just in a different version.
UPDATE:
Auto Component-GUIDs: WIX now has a new auto-generate component GUID feature that calculates a GUID as long as the target path
stays the same. I have not tried this out to be honest, but many seem
to use it without problems, and Rob Mensching (Wix author) states it is safe for normal use. As a concept I highly recommend this
since it features some auto-magic and shields you from some
complexity.
Minimal WiX Markup: Also note that you can leave out a lot of source attributes from
your Wix xml file and rely on Wix defaults instead of hard
coding values.
You never change the Component/#Guid. You also never change the set of Resources (File, RegistryKey, Shortcut, TypeLib, etc.) in the Component. When you have a new Resource, you must create a new Component with a new #Guid. The really tricky part is that new Component can have no overlap (think file path, or registry key path, or typelib, etc.) with the old Component.
These are basically the Component Rules, check out: https://robmensching.com/blog/posts/2003/10/18/component-rules-101/.
Have a look at the WiX Tutorial, The Files Inside, for a detailed explanation on component rules. Basically, it says you never change the GUID of a component, since that means orphaning the old component and creating a new component.