Executing a custom action that requires elevation after install - wix

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.

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>

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.

Related

Enable logging in wix installer

How can I enable logging in my wix project and set MsiLogFileLocation?
Now I am running my install.msi with command line arguments:
msiexec /i install.msi /l*v InstallLog.log
I want to log my work always just running install.msi without any arguments. Are there any way to do that?
You can tell WiX to use verbose logging like this:
<Property Id="MsiLogging" Value="v" />
but you can't specify where to write the file - msiexec has already determined that by the time WiX gets to set the property. It'll default to %TEMP%\MSI{random chars}.LOG. You could offer the user a checkbox to determine if they want to open that log, like this (assuming you're using the built in InstallDir UI template - it'd be possible with others as well, but this is a pretty simple example):
<Property Id="MsiLogging" Value="v" />
<UI>
<UIRef Id="WixUI_InstallDir" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="View Installation Log" />
<WixVariable Id="WixUILicenseRtf" Value="license.rtf"/>
<Property Id="WixShellExecTarget" Value="[MsiLogFileLocation]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
This would copy the log file to a directory about as late as possible in the game, but would miss at least some of the tail end of the log:
<Property Id="MsiLogging" Value="v!" />
<CustomAction Id="CopyLog" Execute="immediate"
ExeCommand="cmd /c copy [MsiLogFileLocation] C:\temp\log.txt"
Directory="TARGETDIR"
Impersonate="no"
Return="asyncNoWait" />
<InstallExecuteSequence>
<Custom Action="CopyLog" OnExit="success" />
</InstallExecuteSequence>
Note that this won't work for the C: drive root, because that requires administrative privileges. If you're ok missing even more of the log, you could change OnExit='success' to After='InstallFinalize' and change the Execute attribute on the CustomAction to commit. That should allow it run as administrator.
See this discussion for a bit more: http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Setting-MsiLogFileLocation-property-td7374335.html

WiX created wizard launches the application but doesn't close itself

I would appreciate your help.
I have an installer made by WiX3.8. I needed to start application after having fulfiled installation. I found this HowTo.
In a word my application is launched, but I still have instalation wizard working. And if I press finish again the app launches again too.
So, there are two part of my wixfile:
I have CustomAction
<Property Id="WixShellExecTarget" Value="[#file19_launcher]" />
<CustomAction Id="LaunchApplication" Execute="immediate" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
and ExitDialog in a ui section:
<UI Id="GoWixUI_InstallDir">
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchApplication" Order="1">NOT Installed</Publish>...</UI>
Please give me any suggestions you have on it.
Thanks.
Ok. I was forced to create my own Finish Dialog and add sequence of actions for finish button. But if someone knows why it doesn't work as it was mentioned, please welcome )

Wix Custom Action Not working in another machine

i have created a custom action for getting sites from IIS server.when i run it in my local machine it's working perfectly.but when i run it in another machine it's not working.
locator for custom action
<"Binary Id ="IisManager" SourceFile="$(var.SourceDir)\bin\CustomActions.CA.dll"/>
("used for foarmat this)
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_Mondo"/>
<UIRef Id="WixUI_ErrorProgressText" />
<DialogRef Id="IisSettings" />
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="IisSettings" Order="3">LicenseAccepted = "1"</Publish>
<Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="IisSettings">1</Publish>
<InstallUISequence>
<Custom Action="GetIISWebSites" After="CostFinalize" Overridable="yes">NOT Installed</Custom>
<Custom Action="GetIISAppPools" After="CostFinalize" Overridable="yes">NOT Installed</Custom>
</InstallUISequence>
</UI>
have i done something wrong? working only in my machine...
Your custom action is crashing because it's referencing a COM class that is not registered on the other machine. Apparently that CLSID belongs to Microsoft.ApplicationHost.WritableAdminManager and the ServerManager managed API, so if they are not present on the target machine your code will fail. A web search for -CLSID {2B72133B-3F5B-4602-8952-803546CE3344- may get you some more info, but this isn't a WiX or Windows Installer issue as far as I can tell.
Running Setup file with Administrative privileges resolved the issue.
CMD ->>Run As administrator -> Go To setup file and Run it.

WIX. Set environment variable and run application after installation

I developed a custom installer with WIX for a .NET application.
In this installer I set environment variable
<Environment Id="COMPLUS_Version" Action="set" Part="all" Name="COMPLUS_Version"
Permanent="yes" System="yes" Value="v4.0.30319" />
and after installation I run application (this environment variable need to be set for correct running apllication).
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_Advanced" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WixShellExecTarget" Value="[#Application]" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
But, sometimes it doesn't work. For example, in Windows 7 Enterprise x86 apllication run after installation with errors (only after installation).
UPD. This problem appear when UAC is disabled.

How do I execute file installed by merge module?

I am using WIX and have successfully used a custom action to execute installed file at the end of installer like this:
<CustomAction Id="LaunchAfterInstall" FileKey="foobar.exe" ExeCommand="parameters" Execute="immediate" Impersonate="yes" Return="asyncNoWait" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION"/>
<UIRef Id="WixUI_InstallDir" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Foobar." />
<UI>
<Publish Dialog="ExitDialog" Control="Finish" Order="1" Event="DoAction" Value="LaunchAfterInstall">WIXUI_EXITDIALOGOPTIONALCHECKBOX</Publish>
</UI>
This works well when foobar.exe is in a component in the same wxs file. However what I really want is to execute a file that is installed by a merge module. How do I do this?
I can make changes in the merge module, if this helps things.
I changed the action to solve my problem:
<CustomAction Id="LaunchAfterInstall" Directory="INSTALLLOCATION" ExeCommand="[INSTALLLOCATION]\foobar.exe" Execute="immediate" Impersonate="yes" Return="asyncNoWait" />
You can also open the Merge Module in Orca or your MSI after the build is complete (i.e. the Merge Module has been merged in) and look up the File.Id. Then use the File.Id in the CustomAction.
Ideally though the MSI shouldn't refer to content inside the Merge Module since Merge Modules are supposed to be independent. I appreciate it doesn't always work out that way. :)