WIX get runtime variable from msi to transform another - properties

I'm implementing exe installer with two msi. During installation of first one user have to select value from ComboBox and I want to use selected value as parameter to run transformation on second msi. I'm using dotNetInstaller bootstrapper (with no UI) and have to configure msiexec parameters as TRANSFORMS="[variable from first msi]"
I tried to use system variable but it wan't work. How can I get ui-property value to transform second msi?

Based on your current design, I'd say the simplest way is for the first MSI to store the property in a registry value and then have the second MSI ( or a transform of the second MSI ) read the registry value into a property.
Normally I'd have your boostrapper/chainer (EXE) do the UI and then pass the values to the child packages.

Related

How to find whether the MSI has InstanceTransforms enabled or not?

We have an WPF based external UI application i.e setup.exe which wraps the msi's developed in WiX. We have a requirement that some components/msi's requires multiple instance support and some don't require multiple instance support but all components are part of single package.
We pre-defined InstanceID's, ProductCode and UpdgradeCode for each instances during build time. Because creating instance ID on the fly create complexity in the patch/upgrade scenarios.
We want Setup.exe to do 2 things,
1. It should lookup the target computer and detect if any component is installed already. To do that Product code required.
2. It should automatically detect the msi's copied into the path and lookup the InstanceTransforms exist or not in the msi. If InstanceTransforms found then it should fetch the Instance ID's defined. Because we don't want to keep any business logic in Setup.exe. Reason is to avoid recompile Setup.exe every time we change the msi.
Now Setup.exe will know whether the msi requires instance ID or not based on that it will invoke the msi and pass commandline parameters. It's kind of plugin mechanism to avoid regression.
Issue:
We could not retrieve the InstanceTransforms from MSI maybe because it's not a property. We have checked the _Storages table and property table but we could not figure it out.
How can we retrieve the InstanceTransforms element and it's Instance definition (InstanceID and ProductCode) in the msi?
Please advise.
#Christopher Painter
I don't follow your question exactly. In general you can use the WiX DTF Microsoft.Deployment.WindowsInstaller library to do queries against the MSI database and MSI API. You can query the Property table to get the ProductCode then query installed products to see if it's installed. To see if the MSI has embedded transforms available you can query the _Storages stream, apply the transform and then read the properties for those also.
I'm adept at WPF/MVVM development if you want to hit me up for more detailed consulting.

WiX - Dynamically changing name of installed product in Add/Remove Programs

I am working on an installer with WiX which takes a "name" input from the user using a textbox in a dialog. This name will be used to name the product that i am installing.
But, i am not able to set the product name dynamically during install. Even if i use a custom action, the registry entry is getting created with the static name that i have provided earlier. This is ultimately leading to inconsistency.
Can anyone please help me regarding this?
This cannot be done in a custom action. It's true that you can set the ProductName property in a custom action (such as a type 51) early in the install and that will indeed change the name in the UI, but it will NOT change the name of the installed product - it will remain the same as the original value. For example, enumerating installed products will return the original name.
So the only good way to do this is to modify the ProductName in the MSI file before you launch it. You would have a launching program that modifies the MSI file and then installs it. The MSI file is a database that can be modified in the Property table to change the value of ProductName. This example will give you the general idea:
How do I add/update a property inside an MSI from the command-line?
but basically you open the open the database (MsiOpenDatabase or equivalent) then MsiOpenView with a SQL such as:
"UPDATE Property SET Property.Value = 'Your variable' WHERE Property.Property = 'CurrentProductName' "
then MsiViewExecute and close handles etc. Details depend on your preferred coding language environment.
This is not an ideal solution because if your MSI file is digitally signed you have tampered with it and it is no longer correct.
Another way is to generate a transform file, based on altering a copy of the MSI file. If you make a copy of the MSI file, and then do the alteration of ProductName as above you can then do an MsiDatabaseGenerateTransform() call which will generate a transform file, a .mst file, the difference between the two MSI files. You then install the original unaltered MSI file with a command line that includes TRANSFORMS=[the .mst file] which will update the ProductName and start the install.
None of this is very easy because Windows Installer products are not designed to have dynamic product names. Maybe historically and before Windows Installer setups this was more practical, but not in MSI setups.

Overwrite MSI DisplayVersion with Custom String

I have a .msi installer (via wix) for an application I'm working on but the application's version number doesn't fit the X.Y.Z version numbers required my MSI's registry Version so the version number is "mangled" into something that does fit and still increases with every release.
I'm okay with this.
msiexec, as part of it's final cleanup, converts this X.Y.Z integer-encoded version number into a string and dumps it into the DisplayVersion registry entry. What I'd like to do is overwrite that string with my own that contains the actual version number of my application.
This certainly seems possible. For example...
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\19BF4688EE4961F41A44D0282A2340D9\InstallProperties
DisplayName = (REG_SZ) "Configuration Manager Client"
LocalPackage = (REG_SZ) "C:\Windows\Installer\41202.msi"
DisplayVersion = (REG_SZ) "5.00.7958.1000"
Version = (REG_DWORD) 0x05001f16
The Version is the encoded value of "5.00.7958", so where did the rest of the DisplayVersion string come from?
How, using only wix/msi supported options, do I overwrite DisplayVersion in the registry with my own custom string?
Might be a larger change than what you're looking to make, but...
if you set ARPSYSTEMCOMPONENT=1 in your MSI it won't register an ARP entry for your product. Then you can create your own ARP entry for your product by populating the HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductCode] keys in the Registry table of your MSI.
I eventually accomplished this by having the MSI launch a custom installer binary near the end of the installation procedure. That program forks a background copy of itself and exits so that the install can finish.
The background task sleeps for a while to let the installation complete and then directly alters the registry to set DisplayVersion to the desired string.
There's a race condition here but it hasn't been a problem and updating the string isn't essential.

Update property value with changes made in registry during install

I have a WiX project in which there is a need to check for certain registry keys that should be added as part of install.
But using the RegistrySearch element, as it is scheduled with AppSearch execute sequence, I always end up getting a blank value because till AppSearch no keys are written.
Is there any way I can determine existence of Registry keys somewhere around PostInstall?
This question is somewhat similar to : this question
Why do you need a search to see if a registry from the package is installed or not? You could simply just check the state of its component. If the state say the component got installed it means the registry is on the machine, and vice versa.
Condition examples.

How to set conditions that have dependencies in WiX?

I am making an installer, which need read a registry key and get a value, then use this value to access another registry then get the INSTALL dir.
Any condition mentioned above will stop the installation if fails.
How to set such conditions that one is dependent on the other?
Thanks.
Use RegistrySearch then a Condition element in the Product element using the Property from the result of the RegistrySearch.