Run PowerShell script from WiX installer
Looks like you have scheduled the CAQuietExec action as deferred. In this case you have to pass the command line to be executed via a CustomActionData property called QtExecDeferred which is written to the execution script. The deferred action can then access the property from the script.
More details at http://wixtoolset.org/documentation/manual/v3/customactions/qtexec.html
I didn't understand Stephen's answer, however I eventually got it working with the help of this blog post.
Here's a summary of the change I made to Greg's code to get it to work:
I changed
CAQuietExec
toWixQuietExec
(I'm not sure if this was necessary).In
SetProperty
I changed the value of theBefore
attribute fromInstallFiles
to theId
of the custom action; in Greg's case it would beRunPowerShellScript
.Although unrelated to the question, I ended up needing to change the
-Version
of powershell to3.0
from2.0
to prevent an error when running my script.
Here was my actual working code:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"> <Product Id="*" Name="..." Language="1033" Version="..." Manufacturer="..." UpgradeCode="..."> <Property Id="POWERSHELLEXE"> <RegistrySearch Id="POWERSHELLEXE" Type="raw" Root="HKLM" Key="SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" Name="Path" /> </Property> <Condition Message="This application requires Windows PowerShell."> <![CDATA[Installed OR POWERSHELLEXE]]> </Condition> <SetProperty Id="InstallMongoDB" Before ="InstallMongoDB" Sequence="execute" Value=""[POWERSHELLEXE]" -Version 3.0 -NoProfile -NonInteractive -InputFormat None -ExecutionPolicy Bypass -Command "& '[#MONGODB_INSTALL.PS1]' ; exit $$($Error.Count)"" /> <CustomAction Id="InstallMongoDB" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="check" Impersonate="yes" /> <InstallExecuteSequence> <Custom Action="InstallMongoDB" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom> </InstallExecuteSequence> <Component Id="MONGODB_INSTALL.PS1" Guid="..." DiskId="1"> <File Id="MONGODB_INSTALL.PS1" Name="mongodb-install.ps1" Source="mongodb-install.ps1"/> </Component> </Product> <Fragment> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="APPLICATIONFOLDER" Name="..."> <Directory Id="InstallScripts" Name="InstallScripts"> <Component Id="MONGODB_INSTALL.PS1" Guid="..." DiskId="1"> <File Id="MONGODB_INSTALL.PS1" Name="mongodb-install.ps1" Source="mongodb-install.ps1"/> </Component> </Directory> </Directory> </Directory> </Directory> </Fragment></Wix>
Only the following example helped mehttps://github.com/damienbod/WiXPowerShellExample/blob/master/SetupWithPowerShellScripts/Product.wxs
you need to add smth similar into your 'Product.wxs'. the 'Value' property of the first 'CustomAction' contains a ps script (create and run a windows service in my case).
<!-- assign the string (ps command) to RegisterPowerShellProperty --><CustomAction Id="RegisterWindowsService" Property="RegisterPowerShellProperty" Value=""C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInteractive -InputFormat None -NoProfile sc.exe create MyService binpath= 'C:\Program Files (x86)\My service\MyService.exe';sc.exe start MyService" Execute="immediate" /><!-- Deferred execution of the above script --><CustomAction Id="RegisterPowerShellProperty" BinaryKey="WixCA" DllEntry="CAQuietExec64" Execute="deferred" Return="check" Impersonate="no" /><InstallExecuteSequence> <!-- On installation we register and start a windows service --> <Custom Action="RegisterWindowsService" After="CostFinalize">NOT Installed</Custom> <Custom Action="RegisterPowerShellProperty" After="InstallFiles">NOT Installed</Custom></InstallExecuteSequence>
you will need to add a reference to 'WixUtilExtension' in order to run the script.