WiX with dynamical resources - wix

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.

Related

Installing a binary if it is already present using WIX installer

Background : Customers have been copying a set of binaries and putting it on a specific location for them to run NinjaTrader Indicators. For Eg: lets assume The customer "A" has used First.dll, second.dll and Customer "B" has used First.dll and Third.dll (they did not use any installers, but just copied from a server location)
Current Requirement: I have to create a WIX installer with all possible updated DLLs with a caveat that it should install only those updated dll whose previous version customer has already on his machine. So if the new WIX installer has First_1000.dll, Second_1000.dll, Third_1000.dll and Fourth_1000.dll, then it should behave on Customer "A" and "B" as follows:
Customer "A": Uses this installer, his machine should have only First_1000.dll and Second_1000.dll and not others.
Customer "B": Uses this installer, his machine should have only First_1000.dll and Third_1000.dll and not others.
What I have Tried: Using the directorySearch and FileSearch, but I am not able to conditionally install, either it installs all or installs none. Other issue with this is it wont remove the previous version of the binary.
What I need: How to call a CustomAction method and use the return result to make decision to install or not, with this I can remove the previous version of the file as well.
Overall advice: don't approach deployment as a development task first and foremost. Get your files and settings deployed, and do any advanced configuration on application launch.
Do not implement any custom logic if all you need is a file copy and some registry keys - and certainly don't do it all in one custom action using WiX / MSI as a "shell" or "container" only.
There are many tools that can help you deploy your software: How to create windows installer (also lists legacy tools that are not MSI tools).
At one point I wrote this step-by-step answer for a WiX installer.
If you ask me for the easiest way to achieve what you want, then I would install all files via a single MSI and use the application itself to adjust any access to advanced features (if applicable) via the license code (if any). This minimizes your deployment complexity, and puts advanced features in a familiar context: application debugging in user context (most likely).
This avoids a world of pain of custom setup logic - which is very heavily overcomplicated by sequencing, impersonation and conditioningconcerns, not to mention runtime dependencies and other challenges. Collectively this causes the overall problem that setup logic is very hard to debug - due to the collective impact of all these aspects of complexity.
The general approach that should work is to:
Group the components (that contain one file each) into Features that when installed will do the right thing for each customer.
Use Feature conditions based on the results of the file searches and the property values set from the searches.
This example in the WiX docs, Conditional Installation seems to do almost exactly what you're looking for.
In the longer term you should build a setup that doesn't require this type of search behavior. You don't say why the file names change, but I'll guess that you are using the different names as a kind of version control. Installs, patches, service packs, upgrades and so on all replace files based on their binary versions. In a well-designed application and install, the binary versions of the existing files might all be 1.0. If the new files are all versioned 1.1 then all the old files will be replaced. If one was version 1.0 (and therefore unchanged) it would not be replaced. The file names would not change. Version control is the basis for updates, so I recommend moving in that direction.

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 MSBuild automation help - solution best practices

I know there are many questions out there regarding this same information. I have read them all, but my brain is all turned around and I don't know which way to go. Plus the lack of documentation really hurts.
Here is my scenerio. We are trying to use WIX to create an installer for our application that goes out to our dealers for our product information. The app includes about 2000 images and documents of our products and a SQL CE database that are updated via Microsoft Sync Framework. The data changes so often that keeping these 2000 as content files in the app's project is very undesirable. The app relies on .NET Framework 3.5 SP1, SQL Server CE 3.5, Microsoft Sync Framework 1.0 and ADO.NET Sync Services 2.0.
Here are the requirements for the app:
The dealers will be given the app on a CD every year for any updates (app or data updates).
The app must update itself from the internet to get any new images, documents or data.
The prerequisites must be installed if they do not exist on the client machine.
The complete installer should be generated from an MSBuild script with as little human interaction as possible (we don't want to be manually updating the 2000+ file list).
What we have accomplished so far is that we have a Votive project in our solution. We have manually specified the binaries in a .wxs file. Web have modified the .wixproj file to use the HeatDirectory task to gather our data (images and documents and database) from a specified location (This is broken and giving an ICE38 error). This seems all right, but still is a lot of work. We have to manually update our data by running the program in release mode and copying it to the specified directory.
I am looking to see what other people would do in this situation.
How would you arrange your solution with regards to the 2000+ data files? Would you create a custom build script that gets the current data from the server or would you include them as content files in the main project?
How would you get WIX to include all of the project output (including the referenced assemblies) and all of the data files? If you have any complete samples, that would be great. All I have found are little clips here and there and not an entire example from start to finish.
How would you deal with the version numbers? Would you put them as a constant in the build script and reference them through the $(var.VersionNumberName)? Would you have the version number automatically picked up from the project being deployed? If so, How?
If there is any better information than what I am finding, please include. I have read numerous articles, blogs, Stackoverflow questions, the tuturial, the wiki, etc. Everything seems to be in bits and pieces. The tutorial is nice, but doesn't explain anything about MSBuild and Votive. I would like to see a start to finish tutorial on using MSBuild and Votive and all the WIX MSBuild targets. If no one knows of a tutorial like this I may put one together. I have already spent the entire week gathering info and reading. I'm new to MSBuild as well, so if anyone has any great articles on MSBuild, please include them.
The key is to isolate the different types of complexities into separate merge modules and put them altogether into an MSI as part of the build. That way things that change often can change without impacting things that hardly change at all.
1) For the data files:
We use Paraffin to generate the WiX and hence the merge modules for an html + Flash based help system consisting of thousands of files (I can't convince the customer to go to CHM).
Compile these into a merge module all by themselves.
2) Assemblies: assuming that this is a set that changes less often just make a merge module by hand or with WixEdit with the correct files and dependencies.
3) For the version number there a lot of ways to manage this depending on your build system. The AssemblyInfoTask is pretty straight forward way to make sure all your assemblies are versioned appropriately. The MSBuild Extension Pack has some versioning stuff if you are using TFS.
I had a similar scenario and was unable to find a drop in solution so ended up with the following:
I wrote a custom command line program called wixgen.exe for generating wxs manifest files. It is pretty specific to our implementation in that it only knows how to create 2 types of wxs files. One for IIS Website/Virtual Directory deployments and another for Windows Service deployments.
Each time a build is triggered by our continuous integration server a post-build task runs wixgen with the right args to generate a new manifest.wxs for the project being changed. It automatically includes all the files needed for the deployment. These builds also version the dlls using a variation of the technique at: http://richardsbraindump.blogspot.com/2007/07/versioning-builds-with-tfs-and-msbuild.html
A seperate build which is manually triggered is then used to build the wixproj projects containing the generated wxs files and produce the msi's.
I would ditch the CD delivery (so 90's) and got with ClickOnce. This solution seems to fit well since you already use the .NET framework. With ClickOnce you should be able to just keep updating the content of your solution and make updates available to your heart's content. Let me know if you need, sample ClickOnce deployment code.
You can find more ClickOnce information here.
Similar to dkackman's answer, you should seperate your build into several components, isolating build components to be built seperately.
I come from a mainly Java background, however for building MSIs and NET executables we use maven; with the 'maven-wix-plugin' plugin for building the installers, and using the NMaven plugin for compiling any NET code. However, as we're only performing very basic development in NET, with most development in Java, we don't need too much complexity from the NMaven plugin (which is probably a 'good thing' (TM) as it's only at version 0.17).
If you're a purely NET house, you could also look into Blydan (http://www.codeplex.com/byldan), which seems to be the focus of development there at the moment (it's the same team for NMaven and Byldan).
If you do want more information on NMaven or Byldan raise another question and I'll give as much info as I can (which is not a huge amount, as stated I only do very limited NET development).

WIX installer with Multiple Entries in Add/Remove Programs

I am developing installer for a Application Suite using WIX, and the structure is
follows:
Application Core
|_ _ Flavor1
|_ _ Flavor2
|_ _ Flavor3
Application Core is a product like Visual Studio and, Flavors 1,2,3 are sub products under it.
Here is my problem,
- In Add remove programs should have 4 entries for Application Core, Flavor1, Flavor2 and, Flavor3.
- I should be able to relaunch installer for Add/remove Flavor1, Flavor2 and Flavor3.
Update: Note that while Office appears to install separate features, not separate products - it actually installs many separate products that do not display in ARP. A separate ARP entry is added to launch the bootstrapper installer that then maintains adding, removing and updating the existing products that you can't see in ARP.
These should be features, not separate products. Take the Microsoft Office suite for example, if you install the suite then you have only one entry in Add/Remove Programs and Word, Excel, Powerpoint, etc are all just 'features' off Microsoft Office and you update them that way.
However you can purchase some of these applications separately with their own installers and in these cases the "Application Core" as you put it is included with each installer, using shared components so that files don't need to be installed twice and each application can be installed/uninstalled independently of each other.
Here's a little excerpt from the Windows Installer documentation on Components and Features (you may also like to read Organizing Applications into Components)
Two components that share the same
component ID are treated as multiple
instances of the same component
regardless of their actual content.
Only a single instance of any
component is installed on a user's
computer. Several features or
applications may therefore share some
components.
Usually this is accomplished by installing one product, so one entry in Add/Remove Programs, that you can modify (select the product, click the modify button). That then takes you to the feature tree where you can add or remove features.
If separate entries is a hard requirement, you should create multiple MSIs. But then you can uninstall "Application Core" in your example, keeping the others installed, thus causing problems with the Flavors
It does sound like you want features, so Sander gets my +1.
But sometimes you may want different installs of the same product, e.g. a training and test version installed on the same server. In those cases you need to find a different approach, here's one I came up with (see answer Create Live, ...). Take note of the edit about creating a component per file and wildcarding the guid, since this simplifies the process, i.e. no BeforeBuild/AfterBuild tricks required.