How to determine install scope of existing app?

2019-07-25 11:38发布

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?

1条回答
手持菜刀,她持情操
2楼-- · 2019-07-25 12:27

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):

Orca


Throwing in some more links:

查看更多
登录 后发表回答