I have an installer based on the WixUI_Advanced
that allows users to choose their install scope (per user or machine wide).
When upgrading (have an existing app with a lower version installed) I would like to hide the install scope screen and automatically select the install scope they chose last time.
How can I tell what install scope was used for the previous installation?
Edit
Looking at my MSI logs I can see that my existing installation is found:
// Existing user specific installation
FindRelatedProducts: Found application: {C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}
MSI (c) (C4:F0) [11:11:39:289]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}'.
MSI (c) (C4:F0) [11:11:39:289]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}'.
// Existing machine wide installation
MSI (c) (2C:4C) [11:03:19:258]: FindRelatedProducts: current install is per-user. Related install for product '{C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}' is per-machine. Skipping...
I can see the WIX_UPGRADE_DETECTED
and MIGRATE
properties are set only when the existing installation's scope matches the current installation which makes sense. Perhaps I can use FindRelatedProducts
directly?
This is not a complete answer. I had to add as an answer because of
formatting requirements.
UPDATE: Looked at this, ran out of time again. This really is no answer at all, but just lobbing it to you in case it can help you research it yourself
.
Registry Persistence: I assume you have tried to persist ALLUSERS
and / or the installation scope in the registry and read it back in the updated MSI? I didn't look at that. For that to work you have to do it in the first release of the package and keep it up later.
MSI API Automation: Here is a little hack to find the previously installed products on the box (this essentially runs similar stuff as "FindRelatedProducts"
inside MSI files):
Inside MSI:
Set upgrades = Session.installer.RelatedProducts("INSERT-UPGRADE-CODE")
For Each u In upgrades
scope = Session.installer.ProductInfo(u,"AssignmentType")
MsgBox CStr(scope)
Next
Standalone, run script directly (install the MSI with the upgrade code specified first):
Set installer = CreateObject("WindowsInstaller.Installer")
Set upgrades = installer.RelatedProducts("INSERT-UPGRADE-CODE")
For Each u In upgrades
MsgBox "Product Code: " & u & vbNewLine & "Installation Context: " & installer.ProductInfo(u,"AssignmentType")
Next
MsgBox "Done"
I was thinking to do something like this in the GUI-sequence, but ran out of time again:
If scope = 1 Then
Session.Property("ALLUSERS") = "1"
Session.Property("MSIINSTALLPERUSER") = ""
Session.Property("WixAppFolder") = "WixPerMachineFolder"
Else
Session.Property("ALLUSERS") = "2"
Session.Property("MSIINSTALLPERUSER") = "1"
Session.Property("WixAppFolder") = "WixPerUserFolder"
End If
WiX Snippets:
<Binary Id='Scope.vbs' SourceFile='Debugging Custom Actions\Scope.vbs' />
<CustomAction Id='Scope.vbs' VBScriptCall='' BinaryKey='Scope.vbs' Execute='immediate' Return='ignore'/>
<..>
<InstallUISequence>
<Custom Action='Scope.vbs' Before='CostInitialize' />
</InstallUISequence>
I was going to look at this, but ran out of time. Essentially WIX_UPGRADE_DETECTED
will be set in the new setup being installed. See this answer for more. You could use that property to determine whether to hide or show a button. I tested that briefly and it worked, but implementing it in WiX is harder. You need to override the whole dialog I think.
In MSI tables, it would be something like this (Orca screenshot - MSI viewer tools):
- Here is an answer on MSI and Burn GUI issues (please check section 2:
Change Default Dialogs - Advanced Dialogs
).
Throwing in some more links:
- Removing Default dialogs from MSI
- Wix, custom dialog when previous version exists
- Back/Next Button in UI using Wix toolset
- http://neilsleightholm.blogspot.com/2008/08/customised-uis-for-wix.html