Set a WiX burn bootstrapper variable from a bundled MSI? - wix

We have a burn bootstrapper bundle that installs a bunch of prerequisites, launches our main install, then runs a few extension installers silently. We've recently had to add a couple of new components to the installation bundle, both of which require configuration information that's already gathered from other products launched earlier in the install. So basically:
Package 1 is installed and a UI is presented. It asks for a service user and password.
Package 2 was added to our bundle. It also needs a service user and password, the same as for package 1.
Package 3 was added to our bundle. It also needs a service user and password, the same as for package 1.
We'd like to keep from having to have the user configure the same information three separate times. One possible solution we saw was to write our own WiX bootstrapper application, but that seems fairly heavy handed. Another possibility we considered was perhaps there was a way to have package one call a custom action which sets the value of a burn variable. We could then call packages two and three's installers with the burn variable passed in as part of their silent install commandline. Is there a way to do this? If so, what would it involve?

We did eventually find a solution to this, making use of the extended bootstrapper application from Neil Sleightholm. This allows creation of custom actions in the bootstrapper. We created a WiX burn custom action which in OnDetect launches a separate thread. That thread opens a named pipe and listens for pairs of variable names and values to be sent through: when it gets such a pair, it uses the engine's SetVariableValue command to set the value. In the called install, we created a custom action which connects to the named pipe and sends across variable names and values according to what it gathered. The variables' new values successfully get passed on to subsequent installs, however install conditions are evaluated before any installs are launched, so those cannot make use of variables whose values are set by installs.

Related

Windows per-machine install requires reference to original installer when second user runs application

I'm working on an MSI installer written in Wix. The installer works in both per-user, and per-machine contexts.
In a per-machine installation, everything goes smoothly; the product is installed and configured for the initial user. Upon switching to a test user, the application appears in the start menu correctly. Running it for the first time, a msiexec process starts with the message that the app is being configured. However, if the original .msi has been deleted, this process fails.
The failing setup action gives the following message in its log:
Error 1706. An installation package for the product myProduct cannot be found. Try the installation again using a valid copy of the installation package 'myInstaller.msi'.
=== Logging stopped: 3/16/2017 11:15:52 ===
I understand from reading a blog post by Rob Mensching (Lead of Wix) that it probably isn't possible to just edit the source list to point towards the windows cached .msi, a point backed up by another article I've found. Is that correct?
Is there a way to stop this entire action of calling the msi on first run by users from happening? Caching the msi or keeping the original is not ideal, I'd like to use the .msi in a custom bootstrapper that involves deleting the msi once installation is complete.
Microsoft recommends you keep the original MSI available, Rule 31:
https://blogs.msdn.microsoft.com/windows_installer_team/2006/05/24/tao-of-the-windows-installer-part-3/
and I won't repeat what it says about repair/resiliency, but you cannot guarantee the source MSI won't be needed sometime.
You're probably getting this "repair" because there is some resource (a file most likely) that is being installed to a user-profile location. When another user logs on and uses the application that file is missing, so potentially the application is broken. For example a file installed to User's Application Data needs to be available for all users of the system, not just the user that installed it.
So keeping the MSI might not be ideal but is strongly recommended, and in your case of product use by multiple users it's even more likely to required. There should be an Application Event log entry under MsiInstaller that says something about the missing resource.

Custom Bootstrapper bundle - retain entry in add /remove programs on unistalling a single package

I am using Wix 3.8
I want to have a single installer UI which will present four applications.Based on user selection
the particular application has to be installed/ uninstalled /upgraded.
So I added four msis in a custom bootstrapper bundle. In the Custom UI we show all four application names
and based on the user selection I set bundle variable value. Install condition attribute is set to this bundle variable.
Also based on the user selection package list will be updated to have only the relevant package(s) .
In this way install is working fine. Install add only the bundle entry in the Add /Remove Programs; and not individual entry for each msi.
I am also able to manage uninstalling a package based on the user selection.
The issue is while uninstalling one msi package it removes the entry of the bundle from Add/Remove Programs list.
Now how do I uninstall other packages?
The behavior what I need is I want to retain the bundle entry in the Add/remove Programs list ; Once the last package is also uninstalled I want to remove the
entry from Add /Remove Programs List. Please advice me how to achieve this?
I'm going to suggest a different way to approach this problem because it seems to me, and I may be way off base here, that you are implementing something using a bootstrapper when you may only need a single MSI that uses a FeatureTree.
A feature tree can list various categories of things to install or not install. For example, it might ask if you want to install:
Framework only?
Framework and Tools?
Only Tools?
And if the user chooses Only Tools and later decides they want Framework, they can go to Programs and Features, click Change and then they'll be able to select the Framework feature from the Feature Tree.
And if they want to uninstall one thing or everything all together, they can do that too.
If you have control over the four MSIs that you mention, you could change them to be Wix Library projects instead. That would allow you to keep developing them separately, by different teams, but have them all referenced in one MSI project.

Wix optional feature package

We've used wix to create our installer for some time now, but previously we've relied on our customer installing SQL themselves.
I now want to include SQLLocalDB for our smaller customers as an option in our installer, but I don't know the correct way to implement this.
I've added radio buttons to our product to chose between using SQLLocalDB or an external server but how do I pass this variable to the bundle's InstallCondition for SQLLocalDB. I Tried using the registry in between but the registry is read as soon as the bundle msi is started and not after the first package has been installed.
My first idea when I started implementing this was to install SQLLocalDB, create the database and the tables from a custom action, but I've now realized that isn't possible
So to finalize my questions:
How do I add optional features correctly?
If I want to create the database and create/update the tables, do I have to create yet another msi for this and add it as a third package in the bundle?

Can ExePackage update Bundle variable value at runtime

I have written a managed bootstrapper application using WiX toolset's burn API and it works great. Currently it chains 2 MSI packages. Now I need to chain a exe package before the 2 MSIs. This exe package will obtain a value (when it runs) which it needs to pass back to the bootstrapper. Basically, the bootstrapper has a bunch of variables which it uses to populate properties in the 2 MSIs. One of these variables now needs to be updated by the exe package at runtime, so the corresponding MSI property reflects the correct value.
I have looked around and not been able to find anything that indicates that this can even be done. These two links (here and here) speak of similar things, but they all mention that burn variables can be updated at runtime via command-line or within the bootstrapper itself. Not how a ExePackage could pipe back an update to a bundle variable, which is what I need to do.
Would appreciate any feedback.
[UPDATE]
Found a comment by the WiX developer here that points to some sort of communication mechanism between an ExePackage and the bootstrapper.
There's no mechanism to let a package communicate with the Burn engine, other than to indicate success or failure.

How do I create a Setup And Deployment project that can run any number of times on a machine without requiring an uninstall?

How do I create a Setup And Deployment project that can run any number of times on a machine without requiring an uninstall?
I've created an installer to install a WCF service to an IIS directory. It does more than just xcopy, it asks the users questions to correctly setup web.config.
The problem is when it can only be installed once per server without requesting an uninstall.
"Another version of this product is already installed...."
Typically the service will have 10-15 separate instances per server (each instance pointing most likely to a separate database, or a different security context)
I can't figure out how to set up the installer to do this.
Ok, I've got this working, I figured I'd answer it.
I downloaded the Orca windows installer editing tool (Part of the Windows SDK)
In the InstallExecuteSequence table, changed the following values to 0
RegisterUser
RegisterProduct
PublishFeatures
PublishProduct
This should allow the installer to run over and over without uninstalling.
It sounds like your program has 2 parts rolled into 1 - an installer and 1 UI based update service. Could you separate the 2 and have the installer check for being already installed and if so, fire up the UI program to run config setup.
If you want to install multiple versions of the same application you must do 3 things:
Ensure each version installs to a different folder, so subsequent installs will not overwrite previous ones.
You do this by changing the DefaultLocation property of the Application Folder in the File System panel
of the deployment project. A good policy it to use the application version as part of the location; e.g.
[ProgramFilesFolder]\[Manufacturer]\[ProductName]\[ProductVersion].
Ensure the ProductCode property of your deployment project is different, so subsequent installs
will not uninstall the previous version. The easiest way to do that is to...
Change the Version property of your deployment project. Visual Studio will ask if you want to change
the ProductCode property; you do.