Here's the list of my custom actions
<CustomAction Id="LaunchApp" Directory="INSTALLDIR" Return="ignore" ExeCommand="[SystemFolder]cmd.exe /C start somefile.exe" />
<CustomAction Id="CloseApp" Directory="LocalAppDataFolder" Return="ignore" ExeCommand="[SystemFolder]taskkill.exe /F /IM app.exe /t" />
<CustomAction Id="LaunchUninstallPrompt" Directory="dir3D8C2B6BEC447DDCC50D1386BD4CD865" ExeCommand="[SystemFolder]cmd.exe /C start /wait %LOCALAPPDATA%/runtime/bin/java -jar" Return="check" Impersonate='no'/>
<CustomAction Id="DeleteOldSomeFile" Directory="LocalAppDataFolder" ExeCommand="[SystemFolder]cmd.exe /C IF EXIST %LOCALAPPDATA%\someproj (
del %LOCALAPPDATA%\someproj\*.* /s /q
rmdir %LOCALAPPDATA%\someproj /s /q
)" Return="ignore"/>
and here's my install current sequence
<InstallExecuteSequence>
<Custom Action="CloseApp" Before="InstallValidate" />
<Custom Action="LaunchApp" After="InstallFinalize">NOT REMOVE</Custom>
<Custom Action="LaunchUninstallPrompt" Before="InstallValidate">REMOVE AND NOT UPGRADINGPRODUCTCODE</Custom>
</InstallExecuteSequence>
I want the Action 'DeleteOldSomeFile' to be executed right after "CloseApp" How would I specify that?
You can use sequence number instead of Before/After attributes:
<Custom Action="CloseApp" Sequence="1398" />
<Custom Action="DeleteOldSomeFile" Sequence="1399" />
You can set "before" dependencies like this:
<Custom Action="CloseApp" Before="DeleteOldSomeFile" />
<Custom Action="DeleteOldSomeFile" Before="InstallValidate" />
Related
I have the following custom actions which normally remove the exe from windows service and add it back,
<CustomAction Id="ExecRemoveService" Directory="INSTALLDIR" Execute="immediate" ExeCommand="MyExe.exe -remove" Return="ignore" />
<CustomAction Id="ExecInstallService" Directory="INSTALLDIR" Execute="immediate" ExeCommand="MyExe.exe -install" Return="ignore" />
<InstallExecuteSequence>
<Custom Action="ExecRemoveService" After="InstallFinalize" />
<Custom Action="ExecInstallService" After="InstallFinalize" />
</InstallExecuteSequence>
When run the MSI nothing happening, it successfully finish but nothing inside windows service I am seeing.
This one worked for me,
<CustomAction
Id="ExecInstallService"
Directory="INSTALLDIR"
Execute="deferred"
ExeCommand='cmd.exe /k "MyService.exe -remove & MyService.exe -install & exit"' Return="check" Impersonate="no" />
I've got to silently run some cmd line on uninstall. I'm trying to use WixSilentExec but it does not work. What is the problem ?
<Property Id="WixSilentExecCmdLine" Value='cmd /C "rmdir /s/q [DataBaseDir]"' Hidden="yes"/>
<CustomAction Id="RemoveDataDir" BinaryKey="WixCA" DllEntry="WixSilentExec" Execute="immediate" Return="ignore"/>
<InstallExecuteSequence>
<Custom Action="RemoveDataDir" Before="RemoveFiles">DELETEDATADIR="1" OR FORCEDELETE="1") AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>
<Directory Id="DataBaseDir" Name="$(var.DataBaseDirName)">
<Component Id="DataBaseDir.dir" Guid="*">
<CreateFolder/>
</Component>
</Directory>
The name cmd can not be resolved and quoted executable name should be used instead :"cmd.exe"
SetProperty should be used as the installer can not resolve [DataBaseDir]
Sequence execute should be set
<Property Id="RemoveDataDir" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="immediate" Return="ignore"/>
<SetProperty Id="WixQuietExecCmdLine" Before="RemoveDataDir" Sequence="execute" Value='"cmd.exe" /c rmdir /s/q "[DataBaseDir]"'>1</SetProperty>
I use following configuration to start my server after installation of application:
<InstallExecuteSequence>
<Custom Action='LaunchApplication' After='InstallFinalize'/>
</InstallExecuteSequence>
<Property Id="WixShellExecTarget" Value="[#startServer.vbs]" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Execute="immediate"
Impersonate="yes" />
Installer executes script startServer.vbs at the end of installation procedure.
What property Id should I use if I need to execute several custom actions?
For example if I will use following configuration. What property Id should I use for StopApplication custom action?
<InstallExecuteSequence>
<Custom Action='LaunchApplication' After='InstallFinalize'/>
<Custom Action='StopApplication' Before='InstallValidate'/>
</InstallExecuteSequence>
<Property Id="WixShellExecTarget" Value="[#startServer.vbs]" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Execute="immediate"
Impersonate="yes" />
<Property Id="???" Value="[#stopServer.vbs]" />
<CustomAction Id="StopApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Execute="immediate"
Impersonate="yes" />
UPDATE:
There is error "There is a problem with this Windows Installer package. A script required for this install to complete could not be run." during installation if I use following configuration:
<InstallExecuteSequence>
<Custom Action='StartServerCustomAction' After='InstallFinalize'/>
</InstallExecuteSequence>
<Binary Id='StartServerScript' SourceFile='startServer.vbs' />
<CustomAction Id='StartServerCustomAction' BinaryKey='StartServerScript' JScriptCall='startServerSub' Return='check' />
startServer.vbs
Public Function startServerSub()
Return 0
End Function
I have 2 custom actions running at the same time. How do I schedule them to run after the 1st one has finished. Here is my code:
<CustomAction Id="StartAppOnExit1" FileKey="InterUMIEXE" ExeCommand="" Execute="deferred" Return="asyncNoWait" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="StartAppOnExit1" Before="InstallFinalize">$InterUMIEXE=3</Custom>
</InstallExecuteSequence>
<CustomAction Id="StartAppOnExit2" FileKey="Python" ExeCommand="" Execute="immediate" Return="asyncNoWait" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action ="StartAppOnExit2" Before="InstallFinalize">$Python=3</Custom>
</InstallExecuteSequence>
<InstallExecuteSequence>
<Custom Action="StartAppOnExit1" Before="InstallFinalize">$InterUMIEXE=3</Custom>
<Custom Action ="StartAppOnExit2" After="StartAppOnExit1">$Python=3</Custom>
</InstallExecuteSequence>
Try that and see if it works..:)
I have several properties to set when ALLUSERS is 1:
<CustomAction Id="CA1" Property="InstallDir" Value="[MYINSTALLDIR]" Execute="immediate" />
<CustomAction Id="CA2" Property="Version" Value="2.0" Execute="immediate" />
<CustomAction Id="CA3" Property="x" Value="x" Execute="immediate" />
<CustomAction Id="CA4" ... />
<CustomAction Id="CA5" ... />
<InstallExecuteSequence>
<Custom Action="CA1" After="AppSearch">ALLUSERS=1</Custom>
<Custom Action="CA2" After="AppSearch">ALLUSERS=1</Custom>
<Custom Action="CA3" After="AppSearch">ALLUSERS=1</Custom>
<Custom Action="CA4" After="AppSearch">ALLUSERS=1</Custom>
<Custom Action="CA5" After="AppSearch">ALLUSERS=1</Custom>
</InstallExecuteSequence>
This is working but I'm wondering if there is more concise way instead of tons of CAs and stupid IDs, something like:
<CustomAction Id="CA" Property="InstallDir=[MYINSTALLDIR]; Version=2.0; x=x; y=y; z=z ..." Execute="immediate" />
<InstallExecuteSequence>
<Custom Action="CA" After="AppSearch">ALLUSERS=1</Custom>
</InstallExecuteSequence>
Is this possible?
You could write a C++ custom action that calls MsiSetProperty() a bunch of times. There will technically be more risk for failure though. Once setup, a bunch of set property CA's is usually not that horrible.