1

I want to verify that an MSI is installable by normal users. Is there any way to emulate the permissions flow of an install using UAC without having the graphical prompts?

Background:

I work with an application that is distributed on Windows via an MSI. We do automated testing on it by running msiexec and then testing the resulting application. This works, but we recently ran into an edge case it doesn't cover.

We recently added a CustomAction in our wix setup that is run at the end of the install and which requires elevated permissions to run. The problem is CustomActions, by default, run with Impersonate="yes" which means they run with the running user's permissions and not the elevated permissions granted by UAC.

In our testing, we're running from an administrator context so the install succeeds. However typical users will require a UAC prompt to grant the MSI temporary admin rights to install. Since the custom action is not running with that admin context, the install fails.

So what I want to do is set up an automated test environment that emulates the user experience more closely. UAC is generally designed to not be scripted for security reasons, which complicates the issue. So what I'm wondering is if there's any way to exercise the permissions flow in a way that is automateable, given I have full control over the environment.

Jordon Phillips
  • 11,056
  • 3
  • 31
  • 39
  • Did you find an answer below that is related to what you are working on? Maybe you are doing something more specific testing-wise? – Stein Åsmul Feb 21 '19 at 20:29
  • I never tried, but it should be possible to automate mouse clicks of a virtual machine guest, from the host. From a quick look, [Virtual Box has an API](https://www.virtualbox.org/sdkref/interface_i_mouse.html) that seems to allow exactly this. It is also mentioned in this [Virtual Box forum thread](https://forums.virtualbox.org/viewtopic.php?f=34&t=84504). – zett42 Feb 21 '19 at 21:59
  • [Wrote up this today](https://stackoverflow.com/a/55399651/129130). Looking at your question again. If your run silently via an **`elevated cmd.exe`** there is no UAC prompt at all, and the MSI will install. Any errors & you get an exit code you can detect. If you install a per-user MSI from an **`non-elevated cmd.exe`** that will also work. Complexity comes along if you want to support both modes. Not clear to me if you want to support per-user setups at all? I would just block them - they are anti-patterns. If you need them I would just log in as a regular user and try every major release. – Stein Åsmul Mar 28 '19 at 16:00

1 Answers1

0

Elevated Rights: A per-machine setup can run with temporary admin rights - as you put it - without being a per-user install. This is done via Group Policy / Active Directory and distribution systems that handle this kind of scenario properly.

Emulate Elevated Rights: To emulate the elevated rights on a regular PC (without a distribution system), you can use a group policy / registry hack called AlwaysInstallElevated. Once applied, it essentially means that all users can run with elevated rights just launching an MSI. Sizable security hole, so don't use it for fun. You can, however, kick off any install and install with elevated rights - if that is what you need.

Deferred Mode Custom Action: Only deferred mode custom actions have elevated rights. Immediate mode custom actions can not elevate and if they try to do something to the system that requires admin rights you will get a runtime error. If you run such a failing MSI with "real" admin rights, then you will see the MSI appear to successfully install (though it will fail with elevated rights for a standard user).

Implementing a deferred mode custom action generally (for non-trivial purposes) requires some involved steps. Perhaps you are familiar with them? You can't access properties directly, you need to "send them to deferred mode" via a mechanism called CustomActionData (SO). And adding a marginal WiX sample for deferred mode.

Lobbing you some links for now (too many, but just thought I'd hand you the bunch - I think the first link will do, 5 for classic technical article, 6 for a modern approach using JSON):


Privileged: If you want to ensure that the MSI package installs per-machine properly for a standard user, I would add a launch condition to the MSI to abort if privileged rights are not available (no chance of success). Note that this does not check for admin rights, but for privileged rights (elevated rights).

<Condition Message="Elevated rights required to install package.">Privileged</Condition>

msiexec.exe: And just for the record, adding a little batch to check for msiexec.exe error codes (not tested recently, but here goes - note that a number or error codes indicate success - for example "reboot initiated" and stuff like that):

1603 = Fatal error. See link above for more.

start /wait msiexec.exe /i Setup.msi /l*v Setup.log

if "%errorlevel%" == "0" goto OK
if "%errorlevel%" == "1603" goto err
if not "%errorlevel%" == "0" goto err

:OK
GOTO END

:err
rem print message and return errorlevel
echo "Error: Msiexec failed with errorlevel = %errorlevel%"
exit /b %errorlevel%

:END

Note that a number of exit codes indicate success (beyond just 0):

1641: ERROR_SUCCESS_REBOOT_INITIATED
3010: ERROR_SUCCESS_REBOOT_REQUIRED

There are probably others I have forgotten. Sample only.

Stein Åsmul
  • 34,628
  • 23
  • 78
  • 140