UAC in MSI Notes: How do I get the shield on the advertised shortcut?

This is the nineteenth 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
    4. The NoImpersonate Bit Mistake
  4. More Architectural Insights
    1. My "Four Square" Diagram
    2. Challenges for a Beautiful Custom Action
    3. O Whitepaper, Where Art Thou?
    4. Read the Friendly Manual
  5. Conversations with Customers
    1. Should I write my installer as a Standard User install? If yes, how?
    2. When General Custom Action Mitigation Fails

This entry continues a section specifically focused on Question and Answers that often come up in the UAC in MSI dialogs.  For this topic, the question is: how do I add shield to my advertised shortcut?

My application is advertised. How do I get the shield on the advertised shortcut?

If you are a developer of an Administrator-Only Application, you will need to manifest your application itself to get the credential prompt appropriate to the users’ rights. If you install supports advertised shortcuts you will also need to manifest your icon. Here's a quick walkthrough for what you need to add a Shield to your shortcut.

Base Generation of an Icon EXE for your Advertise Shortcut

Here's how one generates the icon only exe for advertised shortcut

  1. Generate an icon.ico file.
  1. Generate the icon.rc file
 //
 // base resource script.
 //
 #include "resource.h"
  
 /////////////////////////////////////////////////////////////////////////////
 //
 // Icon
 //
  
 // Icon with lowest ID value placed first to ensure application icon
 // remains consistent on all systems.
 IDI_ICON1               ICON                    "icon.ico"
  1. Generate the resource.h file
 // Used by icon.rc
 //
 #define IDI_ICON1                101
  1. Build the icon.res file
 c:\icon>rc icon.rc
  1. Build the icon.exe file
 c:\icon>link icon.res /noentry /machine:x86 /dll /out:icon.exe
  1. And now you have your initial icon.exe
 c:\icon>dir /o:d
 
 1,078 icon.ico
   421 icon.rc
    71 resource.h
 1,912 icon.RES
 2,560 icon.exe
    
  1. that you have been referencing with the Shortcut table Icon_ column

Shortcut

Directory_

Name

Component_

Target

Arguments

Description

Hotkey

Icon_

IconIndex

ShowCmd

WkDir

AdministratorTool

AdminToolsDirectory

Admin.exe

AdminTools

AdminTools

 

 

 

icon.exe

 

 

 

  1. foreign key to the Icon table

Name

Data

icon.exe

[Binary Data]

Generate an icon.exe.manifest file.

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <assemblyIdentity version="1.0.0.0"
      processorArchitecture="X86"
      name="Icon"
      type="win32"/>
   <description>Description of your application</description>
   <!-- Identify the application security requirements. -->
   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
     <security>
       <requestedPrivileges>
         <requestedExecutionLevel
           level="requireAdministrator"
           uiAccess="false"/>
         </requestedPrivileges>
        </security>
   </trustInfo>
 </assembly>
  
  1. Augment the icon.rc file
 //
 // Tweaked resource script.
 //
 #include "resource.h"
  
 
  ///////////////////////////////////////////////////////////////////////////// 
  // 
  // Add Shield - per http://msdn.microsoft.com/library/en-us/dnlong/html/AccProtVista.asp
  // 
  #define MANIFEST_RESOURCE_ID 1
 MANIFEST_RESOURCE_ID RT_MANIFEST "icon.exe.manifest" 
  
  
 /////////////////////////////////////////////////////////////////////////////
 //
 // Icon
 //
  
 // Icon with lowest ID value placed first to ensure application icon
 // remains consistent on all systems.
 IDI_ICON1               ICON                    "icon.ico"
  
  1. Rebuild the icon.res file
 c:\icon>rc icon.rc
  1. Rebuild the icon.exe file
 c:\icon>link icon.res /noentry /machine:x86 /dll /out:icon.exe
  1. And now you have your manifested icon.exe
 c:\icon>dir /o:d
 
 1,078 icon.ico
    71 resource.h
   421 icon.rc
    600 icon.rc
    657 icon.exe.manifest
  1,916 icon.RES
 3,072 icon.exe
  

Why the second manifest anyway?

The way the Windows Installer enables advertised shortcuts is by pointing Windows the shortcut icon to a cached EXE and putting a Darwin Descriptor in the target path. Dividing a package this way enables the CreateShortcuts action in the AdvtExecuteSequence table to populate the Advertised shortcut. When the user clicks on the shortcut, the Darwin Descriptor is decoded by the Windows shell into parameters that are passed to the Windows Installer.

Windows Installer will evaluate if the thing pointed as is present locally and install it if it's not. Due to the caching of credentials with Windows Installer 4.0 support for User Account Control, the Windows Installer will not prompt for credentials. The good news is that even with the dual manifesting one will get just one credential prompt at the launch of the target EXE.