Authoring a single package for Per-User or Per-Machine Installation context in Windows 7

 

Prior to the introduction of UAC in Windows Vista, setup authors were able to create a single package that could install for the current user (“Just for me”) or for all users on the computer (“Everyone”). With the introduction of UAC, setup authors were no longer able to create a single package that could install in both modes. This feature provides the functionality to aid the development of a dual-purpose package for installation on Windows 7.

Historical Perspective:

With the introduction of UAC in Vista, setting ALLUSERS=2 no longer provided the conditional logic to set the installation context based on user’s privileges. As a workaround, Windows Installer provided a way to declare a package is UAC compliant – setting bit 3 of the Word Count Summary property. If this bit is set, no elevation prompt is thrown – and the package is installed per-user. It is the responsibility of package author to ensure that there are no writes to per-machine locations and that elevated privileges are not required for installation; otherwise the installation would fail due to a lack of privileges.

This meant that the setup authors typically had to create two packages for Windows Vista – one with the UAC compliant bit set for per-user installation; and other without this bit, for per-machine installation. Also, setup authors had to ensure – in a per-user installation – that the common locations like ProgramFilesFolder were not used, because there were no per-user equivalents for them in Windows Vista.

Introducing dual-Mode Package:

With Windows Installer 5.0 on Windows 7 and higher, you can author a dual mode package that can be installed per user or per machine. Setup authors can set the MSIINSTALLPERUSER property to 1 and ALLUSERS to 2 to identify the package as a dual-purpose package. Note that MSIINSTALLPERUSER is only evaluated when ALLUSERS=2. These properties can be specified in the package, passed through the command line, modified by a transform, or – more commonly – selected through a user interface dialog.

Adhere to these Development guidelines for dual-mode packages to ensure your package can be installed in either the per-user or per-machine context. Windows 7 SDK includes a sample package PUASample1.msi to serve as an example of how to author a dual mode package.

Per-user capable known folders and registrations of the Windows Shell:

Prior to Windows 7, an app installed in the per-user context, only had its entry-points like shortcuts, installed per-user – the app binaries and registrations were (unless specified as per-user) written in per-machine locations like “Program Files” and HKLM, since there were no per-user equivalents for some of these locations. Windows 7 includes support for a per user equivalent version of FOLDERID_ProgramFiles and FOLDERID_ProgramFilesCommon as well known folders. These folders will be automatically created by Windows Installer if they do not exist.

FOLDERID_UserProgramFiles: “%LocalAppData%\Programs”.

FOLDERID_UserProgramFilesCommon: “%LocalAppData%\Programs\Common”.

As the author of a Windows Installer package, you simply continue to use the existing Windows Installer properties ProgramFilesFolder and CommonFilesFolder. At install time, Windows Installer will redirect to the per-machine version (i.e. the version that is globally available to all users) or the per user version that is available for the current user for whom the application is being installed. Note that the ProgramFilesFolder and ProgramFiles64Folder have the same per-user equivalent on a 64-bit system; similarly for CommonFilesFolder and CommonFiles64Folder. The MSDN article on Installation Context describes automatic redirection of various properties, registry keys, and shortcuts based on the context in which a package is installed.

Developing for multiple Windows platforms:

Dual mode packages are only recognized on Windows 7 and above. The MSIINSTALLPERUSER property will be ignored on down-level systems. ICE 105 is provided to help you verify that your package can truly be installed in either mode. It basically verifies that your package is not writing to any machine-wide locations. The table below explains the behavior of different kinds of installations on various platforms:

Some things to consider…

The target customers for dual mode packages are LOB ISVs who author lightweight applications that don’t need administrative privileges and don’t need to write to machine-wide locations during installation. So, there are cases where a per-user or dual mode package would not serve the purpose:

· If there are any machine-wide prerequisites, you will have to install them separately.

· Per-user apps are not supported by some OS Registration points, you cannot install services or drivers or global assemblies, etc.

· Apps that are meant for all users – like firewall or anti-virus cannot be installed per-user.

· A per-user package will only be serviced when the user who installed it, is logged on to the machine.

· Also, “Set Program Access and Defaults (SPAD)” cannot be set for apps installed as per-user installation context.

FAQ’s

Q: If the MSIINSTALLPERUSER and ALLUSERS properties can be specified in the package, through the command line, or via the UI, what takes precedence?

A: Precedence of properties in decreasing order of priority

1. What is specified via UI

2. What is specified in command line

3. What is set in package

 Note that the both MSIINSTALLPERUSER and ALLUSERS properties should be set at the same time. For example, you should not set ALLUSERS property via command-line and MSIINSTALLPERUSER property via UI.

 

Q: What about servicing for a per-user installed app?

A: Once a dual mode application is installed per-user, it can be serviced (patched/repaired/uninstalled) by a standard user, with no UAC prompt or elevation needed assuming the user is logged on.

 

Q: Can per-user and per-machine installations of the same app co-exist on the same machine?

A: It depends. If the app is first installed per-machinethe app will already be visible to all users and cannot be installed per-user. However, if a standard user Jane installs an app per-user, another user Abby can install the same app per-machine, assuming she has admin credentials. Jane will continue to see and use her version of the application on shortcuts, start menu, etc. If Jane removes her version of the application from “Uninstall or Change Program” wizard, she will then see the per-machine version of the application.

In the “Uninstall or Change Program” wizard, Jane would be able to see both the per-user and per-machine versions of the app, but she would not be able to uninstall the per-machine version without providing administrator credentials. She would, however, be able to uninstall (or repair) her per-user version of the app without seeing a UAC prompt. Abby will only see the per-machine version that she installed and made visible to all users on the system.

Q: Okay, if per-user and per-machine versions of an app can co-exist, which version gets updated when a patch is ready to be installed?

A: This depends on the context that the app was originally deployed and the context that the patch is being applied. For instance, let’s imagine that standard users Jane and Toby have both installed an app per-user, before the administrator Abby decided to install it for all the users on the machine. If Jane is logged on when the patch is to be applied, then her version of the app will be updated, and she will not be presented with a UAC prompt. Same holds for Toby. When Abby is logged on, the per-machine version of the app will be updated.

 

Q: I manage an enterprise environment where I would like to block users from installing applications per-user. What can I do?

A: Setting the policy DisableMSI to 1 will block the per-user install operations of dual mode packages. Setting it to 1 will also block all the uninstall/patching/upgrade of the packages that were previously installed with MSIINSTALLPERUSER=1. Setting the DisableMSI to 2 will block windows installer from doing any operations on the machine. Setting the DisableUserInstalls policy to 1 disables install/uninstall/upgrade/patching of per-user applications.

 [Authored by Ashish Awasthi & edited by Zainab Hakim]

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm.