Executing a custom action that requires elevation

2020-03-19 08:39发布

问题:

I have the following WiX snippet:

<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
<CustomAction Id="StartAppOnExit" 
              FileKey="Configurator.exe" 
              ExeCommand="" 
              Execute="immediate" 
              Impersonate="yes" 
              Return="asyncNoWait" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" 
          Value="Configure initial settings" />
<UI>
  <Publish Dialog="ExitDialog" 
           Control="Finish" 
           Order="1" 
           Event="DoAction" 
           Value="StartAppOnExit"
  >WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>

Basically on the exit dialog I display a box that says: launch application. Note: this application requires elevation. This all works fine except for a snag. If UAC is enabled it seems that the MSI mucks around with the user token and strips its groups, so when it tries to launch the application that requires elevation it is no longer an option.

How do I string this together to work?

I tried chucking an Impersonate="no", but it's too late at that point for this to work.

回答1:

The UI sequence is running as a limited user, and it launches applications with a call to CreateProcess. If you use something like a WixShellExec with [WixShellExecTarget] instead, it will act like Explorer and show a UAC prompt if the target requires elevation. Or you could modify your Configurator.exe to allow being launched without elevated privileges, detect that case, and relaunch itself with elevated privileges.

For example, this should work:

<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
<CustomAction Id="StartAppOnExit" BinaryKey="WixCA" DllEntry="WixShellExec" Execute="immediate" Return="check" Impersonate="yes"/>
<Property Id="WixShellExecTarget" Value="[#Configurator.exe]"/>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Configure initial settings" />
<UI>
  <Publish Dialog="ExitDialog" Control="Finish" Order="1" Event="DoAction" Value="StartAppOnExit">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>


回答2:

FYI, Immediate custom actions are ALWAYS impersonated (i.e. they always run as the user who executes the MSI).

I like Michael Urman's idea regarding making your Configurator.exe handle the elevation issue.

I wonder if you could also just include a manifest in your EXE so that the OS knows elevation is always required.