Search code examples
wixwindows-installer

How to determine install scope of existing app?


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?


Solution

  • I ended up checking for an entry with the DisplayName matching our app name in the registry in (inspired by this answer):

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    

    Then I grabbed the content of InstallLocation to determine the install scope:

    if (installLocation == string.Empty)
    {
        // Installed before we introduced scope => never set install location
        return ExistingInstallation.MachineWide;
    }
    else if (installLocation.Contains(_programFilesPath))
    {
        return ExistingInstallation.MachineWide;
    }
    else
    {
        return ExistingInstallation.UserSpecific;
    }