WixSilentExec does not work - wix

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>

Related

Wix CustomAction not executed under Windows7

the following sequence executes correctly on Windows 10 but on Windows 7 seems not to execute:
<Component Id="TargetProgram" Win64="yes" Guid="32BBAECC-AC90-4F79-8E59-8D5B3FA5D4DE">
<File Id="EXE" Source="c:\Windows\system32\sc.exe" />
</Component>
<CustomAction Id="EXECUTE_AFTER_FINALIZE"
Execute="immediate"
Impersonate="no"
Return="asyncWait"
FileKey="EXE"
ExeCommand="config SomeService start=delayed-auto" />
<InstallExecuteSequence>
<Custom Action="EXECUTE_AFTER_FINALIZE" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
Do anybody know what the problem is under Windows7? Thanks.

Wix post-install and pre-uninstall executables

I'm using wix to create an installer for my application in Visual Studio.
I need a post-install executable run after install (which I've got working) and a pre-uninstall executable run before uninstallation.
All of these executables require elevated rights to run (my application, the post-install, and pre-uninstall).
I've scoured the web and stack overflow and found many posts related to this, but none of the solutions seem to work. Either the executables simply don't run, or, on uninstall I get error
There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor.
Here is my Directory layout
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="ROOTDIRECTORY" Name="MyCompany" >
<Directory Id="FOLDERONE" Name="FolderOne" />
<Directory Id="UTILITYFOLDER" Name="Utility" />
</Directory>
</Directory>
</Directory>
</Fragment>
And a snippet of my File layout
<Fragment>
<DirectoryRef Id="UTILITYINSTALLFOLDER">
<Component Id="cmpPreInstallId" Guid="{56DC3D0A-E887-4A94-95B3-72825310DC5D}">
<File Id="filPreInstallId" KeyPath="yes" Source="path_to\PreUninstall.exe" />
</Component>
<Component Id="cmpPosUninstallId" Guid="{DE1DE45E-4D7C-4884-BA3E-EC078E265B7C}">
<File Id="filPostUninstallId" KeyPath="yes" Source="path_to\PostInstall.exe" />
</Component>
<!-- obviously there are other files/components -->
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="UtilityPublishedComponents">
<ComponentRef Id="cmpPreInstallId" />
<ComponentRef Id="cmpPosUninstallId" />
</ComponentGroup>
</Fragment>
And in my Product.wxs
<Product ...>
<!-- The only way I found that actually worked to run the post install was -->
<UI>
<UIRef Id="WixUI_Minimal" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="PostInstallExe">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Perform post-install operations." />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
<Property Id="WixShellExecTarget" Value="[#filPostUninstallId]" />
<CustomAction Id="PostInstallExe"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Impersonate="yes" />
<!-- this does not work to run the pre-uninstall -->
<CustomAction Id="EXECUTE_BEFORE_UNINSTALL"
Return="check"
Impersonate="yes"
Execute="immediate"
Directory="UTILITYINSTALLFOLDER"
ExeCommand="PreUninstall.exe" />
<InstallExecuteSequence>
<Custom Action="EXECUTE_BEFORE_UNINSTALL" Before="RemoveFiles">Installed AND NOT REINSTALL</Custom>
</InstallExecuteSequence>
<!-- other stuff plus the feature -->
</Product>
Anyone with experience see where this might be going wrong?
I've tried many variations of the CustomAction return, impersonate, execute, etc
Finally got it to work, so hopefully this helps someone.
Not sure what the issue was ... but here!
<!-- Setup post install operations -->
<CustomAction Id="PostInstall"
FileKey="key_to_post_install_exe"
ExeCommand=""
Execute="deferred"
Return="check"
Impersonate="no" />
<!-- Setup pre uninstall operations -->
<CustomAction Id="PreUninstall"
FileKey="key_to_pre_uninstall_exe"
ExeCommand=""
Execute="deferred"
Return="ignore"
Impersonate="no" />
<!-- Add pre and post install operations to the installer -->
<InstallExecuteSequence>
<Custom Action="PostInstall" Before="InstallFinalize">NOT Installed</Custom>
<Custom Action="PreUninstall" After="InstallInitialize">Installed</Custom>
</InstallExecuteSequence>

Execute custom actions only on install or uninstall

I'm making installer with WiX 3.10. My original task is to copy Postgres files to target system, initialize cluster, register service, start it and restore database on install, and in reverse - stop service, remove it from system, and clear up cluster data. I wrote two bat files, and added custom actions to execute them and some conditions as described in various places, but none of them working. I've tried with and without CDATA, Installed, INSTALLED and some other variations, but it always executes both actions.
Here is the wix file I'm experimenting with now.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Hatred_6" Language="1033" Version="1.0.0.0" Manufacturer="Satan" UpgradeCode="d9602b10-8428-4031-8c82-99288b21377f">
<Package InstallerVersion="405" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<CustomAction Id="AAction" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" Return="check"
ExeCommand="cmd.exe /c "a.bat"">NOT Installed</CustomAction>
<CustomAction Id="BAction" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" Return="check"
ExeCommand="cmd.exe /c "b.bat"">Installed</CustomAction>
<InstallExecuteSequence>
<Custom Action="BAction" After="InstallFiles" />
<Custom Action="AAction" After="InstallFiles" />
</InstallExecuteSequence>
<Feature Id="ProductFeature" Title="Hatred_6" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Hatred_6" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="CalcComponent" Guid="515C0606-FD73-4B5D-ACF4-481123092A3E">
<File Id="CalcFile" KeyPath="yes" Source="calc.exe" />
</Component>
<Component Id="AComponent" Guid="515e3aa0-e5a0-4cd1-aaa5-ebf25a679a24">
<File Id="AFile" KeyPath="yes" Source="a.bat" />
</Component>
<Component Id="BComponent" Guid="85f7627e-fc39-4f78-a870-221d2d08375d">
<File Id="BFile" KeyPath="yes" Source="b.bat" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
bat files contain dir > a.txt and dir > b.txt so I can see if they actually executed.
It's somewhat frustrating, am I misunderstanding something?
Condition should be placed inside Custom element, not CustomAction. Also, you have no InstallFiles action during uninstalling. Use RemoveFiles instead.
<CustomAction Id="AAction" Directory="INSTALLFOLDER" Execute="deferred"
Impersonate="no" Return="check" ExeCommand="cmd.exe /c "a.bat"" />
<CustomAction Id="BAction" Directory="INSTALLFOLDER" Execute="deferred"
Impersonate="no" Return="check" ExeCommand="cmd.exe /c "b.bat"" />
<InstallExecuteSequence>
<Custom Action="AAction" After="InstallFiles">NOT Installed</Custom>
<Custom Action="BAction" Before="RemoveFiles">Installed</Custom>
</InstallExecuteSequence>

Wix toolkit Executing after another Custom Action

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" />

Wix - change the installation folder based on privilege

I have to create an installation package using Wix. If an admin user is installing the package, it should install into %programfiles%/[applicationName], if the user is an non-admin user then it should install into its local profile folder( LocalAppDataFolder).
How it is possible?
I wrote this for ClickThrough a long time ago. Solution from that looks a lot like this (You provide a Property called "ApplicationFolderName"):
<Property Id="A" Secure="yes" />
<DirectoryRef Id="TARGETDIR">
<Directory Id="ApplicationFolder" Name="App" />
</DirectoryRef>
<Condition Message="Must specify TARGETDIR property when doing an administrative install.">Installed OR (ACTION="ADMIN" AND TARGETDIR<>"")</Condition>
<CustomAction Id="TARGETDIRtoA" Property="A" Value="[TARGETDIR]" Execute="firstSequence" />
<CustomAction Id="SpecifiedA" Property="ApplicationFolder" Value="[A]" Execute="immediate" />
<CustomAction Id="PerMachineInstall" Property="ApplicationFolder" Value="[ProgramFilesFolder]\[ApplicationFolderName]" Execute="immediate" />
<CustomAction Id="PerUserInstall" Property="ApplicationFolder" Value="[LocalAppDataFolder]\Apps\[ApplicationFolderName]" Execute="immediate" />
<InstallUISequence>
<Custom Action="SpecifiedA" Before="LaunchConditions">NOT Installed</Custom>
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="PerMachineInstall" Before="CostFinalize">NOT Installed AND ACTION="INSTALL" AND A="" AND (ALLUSERS=1 OR (ALLUSERS=2 AND Privileged))</Custom>
<Custom Action="PerUserInstall" Before="CostFinalize">NOT Installed AND ACTION="INSTALL" AND A="" AND (ALLUSERS="" OR (ALLUSERS=2 AND (NOT Privileged))</Custom>
</InstallExecuteSequence>
Overriding ProgramFilesFolder property as following should work:
<SetProperty Id="ProgramFilesFolder" Value="[AppDataFolder]" Before="CostFinalize"><![CDATA[ NOT Privileged]]></SetProperty>
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="My Folder">
...
</Directory>
</Directory>
Set property ALLUSERS to 2. See also Single Package Authoring.