This is the twelfth in a series of notes about UAC in MSI. Per the earlier caveat, these are just my notes and not an official position from the Windows Installer team. The previous entries

  1. Introduce...
    1. ...the UAC in MSI Notes series
    2. ...my view of the root problem
    3. ...the conflicting per-user definition
    4. ...it'll be just like Managed Installs
    5. ...the jagged edge to user
    6. ...my relief providing framework
  2. Architecture Insights
    1. The "Saw Tooth" Diagram
    2. Credential Prompt and Permissions
  3. Common Package Mistakes
    1. The AdminUser Mistake
    2. Modify System with InstallUISequence Custom Action
    3. Modify System with InstallExecuteSequence Custom Action Outside of Script
This entry will talk about the forth common mistake we found packages making with UAC in MSI: omitting the NoImpersonate bit for a custom action modifying the system in the InstallExecuteSequence.

Server Custom Actions Modifying the System

Given the pre-Vista operating systems did not enforce the architectural intent to that modifying the system requires the NoImpersonate bit set on a custom action in the InstallExecuteSequence, application compatibility testing found a number of packages that had custom actions failing. Here's the "saw tooth" diagram I draw on my whiteboard to illustrate this mistake.

 

With the permissions changes in the context of UAC, the server-side custom actions inside are script are executed as Standard User by default causes the Application Compatibility problems to show up. The green circle is where this mistake is generally made. Unlike the previous common custom action mistakes, mitigating this problem does not require moving the custom action. This mistake is generally mitigated by the package author flipping the NoImpersonate bit on the custom action.

Conversations Around this Mistake

Generally folks make this mistake due to lack of awareness as they followed that they needed to flip the NoImpersonate bit

If the custom action is logging its errors, the trick is to look for an error code that translates to Access Denied.