Can you share wix fragments between multiple installers? - wix

We are looking to OEM our product complete with separate install paths, exe names, ect...
But of course we want to minimize the amount of maintenance overhead we need to maintain the product.
I know of course that we can re-use the fragment files, and map them to different directories with the product.wxs file. But is it a good idea to do that as we will be reusing GUIDs fro the files.
Now those files will be exactly the same files, but it maybe that they are being installed in different directories.
If anyone could point to some good resources for managing multiple OEM installers with WIX, I'd be very appreciative.

It's ok to reuse ComponentID's in multiple Product contexts. This is basically what merge modules do all the time when consumed by multiple products.
Yes, you can use fragments for code reuse. Here is an old blog article on the subject:
Using the WIX Toolset for Distributed Development
Basically you want to come up with a way of defining your Directory element in your product wxs and then using DirectoryRef elements in your asset fragements. Also your Asset fragments will have Fragment elements and ComponentGroup elements. Then in your Product wxs you can use ComponentGroupRef elements nested under Feature elements to pull the components into your feature.
A couple of rules...
1) You have to pass all the wxs files to candle for the compiler to resolve the symbols.
2) Once you ref something from a fragment ( FragmentRef, ComponentRef, ComponentGroupRef... ) every thing from the fragment gets included. E.g. fragments are atomic and sealed just like merge modules.

Related

WiX: How to mix hand-generated and auto-generated .wxs content?

I have a project that has a large number of files. Between versions of our software, new files get added and some get removed. Therefore, in automating our build process, I would like to have heat auto-generate a .wxs file (let's call it files.wxs).
But then there are certain hand-generated items, like the <product> element with its associated version and <environment> tags for environment variables that we need to set. These never change (except for the version number which increments). Right now, I have put all of that in a file named product.wxs.
How can I best combine them into one .msi? Do I need to create a <component> element inside the <product> element for each of the fragments that were auto-generated in the files.wxs file? If so, that kind of defeats the purpose of auto-generating that file. I'm hoping there is another way.
Help! Thanks, in advance.
The installer that I work on has both manual and heat generated code how ours handle it is:
A script builds the destination file structure i.e. all the files that will be installed are copied to a temp directory mimicking the structure they will have on destination machine
Heat.exe is then executed on that directory structure outputting to a file.
We then apply some transforms as we have multiple features in our installer (though if your installer is just one feature you could use a singular ComponentGroup created by Heat.exe), the transform groups the components into ComponentGroups based off the directory structure.
The manual files only reference the ComponentGroups.
If a file is added or removed the work is done on the script (if necessary, parts of script just scoop whole directories). When the installer is built a new component is automatically generated for that file and it's added to the appropriate group by the transform. No work is needed as that group is already referenced in the manual files.

WiX with dynamical resources

We are developing a software tool that is sold to other software companies to be
redistributed. We deploy our software with WiX. We get some requests from our
clients that they would like to use their own style for the msi (mainly their icons, images
and titles). We do not want to let the customers do the packaging themselves since this
is too sophisticated. Is it possible to create a msi package with WiX, where some
resources as images and strings can be loaded dynamically from external resource later on.
I found Wix: Dynamically Add Features which gives
a solution for dynamically add functionality, but not to change existing parts.
Ok, so here my comment as answer (I hope it was helpful ;-)).
As I don't know the exact use case, I would:
Create the base MSI containing all binaries, bitmaps and icons (in the Binary-table)
After building the MSI, invoke the VBS-script rerplacing the binaries and bitmaps with the ones of your customer.
Send the modified MSI to the customer.
If the changes are rather static you could also create a transform file (.MST) containing all the modifications for your customer. You can then merge this transform into your base MSI file using e.g. WiMerge.vbs from the Windows SDK located in v7.1\Samples\sysmgmt\msi\scripts. This would even simpler and can easily be integrated into your build process.

Wix generate single component id for entire tree

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.

DRY and Component id's in WiX setups with several platforms and configurations

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.

WiX Includes vs Fragments

What's the difference between a WiX include (.wxi file) and a WiX fragment (.wxs file)?
What are the use cases for each?
Which should be used and why?
The file extension is a convenience, the content of the file is what really matters. The distinction makes it easier to manage the difference between the actual installation (wxs files) and the properties required to create the installation (wxi files).
For example, your wxs files specify the product and its contents (which files you install) whereas you would use your wxi files to specify product version, upgrade codes, common paths, etc.
The WiX documentation provides some clear information.
Include files (.wxi)
Source files (.wxs)
Personally, I only use .wxi files to include common <?define?>s. I organize the rest of my product into many different logical groupings of Fragments. Treat Fragments like functions in your typical procedural language. Group like stuff together and don't make them too long.
One thing to be aware of is that adding a wxs file to your project implies that MSBuild will do an incremental build when you update the wxs file. Including a wxi file does not do this.
But on the other hand, MSBuild is not doing automatic builds when any of the files you're including into your msi have been updated, so you're probably not doing incremental builds anyway.