WIX Custom Action running as 32 bit process - wix

I need to get my Custom Action to run as an x64 bit process and am using Visual Studio 2010. When i run the msi i see the following entry in the verbose log file:
Hello, I'm your 32bit Elevated custom action server
and the custom action fails due to wrong processor architecture (I am calling DISM.exe via a batch file). My project is fairly simple:
<DirectoryRef Id="APPLICATIONROOTDIRECTORY" >
<Component Id="Launch.cmd" Guid="{423CD408-F053-496B-8FA7-6C329A2F53BB}" Win64="yes">
<File Id="Launch.cmd" Name="Launch.cmd" Source="C:\Temp\Build\MSU Wrapper for SCUP\Launch.cmd" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="KB977453.cab" Guid="{E8ABB2AE-6F57-4153-B44C-E1083D6702B1}" Win64="yes">
<File Id="KB977453.cab" Name="KB977453.cab" Source="C:\Temp\Build\MSU Wrapper for SCUP\KB977453.cab" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
</DirectoryRef>
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentRef Id="Launch.cmd" />
<ComponentRef Id="KB977453.cab" />
</Feature>
<CustomAction Id="BatchCmd" Property="BatchRun" Value=""[#Launch.cmd]" KB977453" Execute="immediate"/>
<CustomAction Id="BatchRun" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="BatchCmd" Before="BatchRun">NOT Installed</Custom>
<Custom Action="BatchRun" After="InstallFiles">NOT Installed</Custom>
<ScheduleReboot After="InstallFinalize" />
</InstallExecuteSequence>
</Product>
I have x64 release selected in Configuration Manager in Visual Studio. Does anyone have an idea of what is wrong?

Set DllEntry="CAQuietExec64" for x64 custom actions
http://wix.sourceforge.net/manual-wix3/qtexec.htm

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>

Executing Custom Action after adding system variable in Wix

I am adding system variables and then i want to execute custom actions, that depends on those variables. The variables are being added correctly, but the scripts are exiting ( because at that time variables are not there yet ), depsite the fact I am using "After Install Files". Here is my code:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" Name="DataBaseds_Service_Installer" Language="1033" Version="1.0.0.0" Manufacturer="" UpgradeCode="3875ce89-3886-4cbf-b132-01f947ac7a08">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<CustomAction Id="NssmUnzip" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" ExeCommand="cmd.exe /c "unzip.exe nssm-2.24.zip -d "%TANGO_ROOT%\bin" "" Return="ignore" />
<CustomAction Id="Tango_db" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" ExeCommand="[INSTALLFOLDER]create-tangodb.bat" Return="ignore" />
<CustomAction Id ="Baseds_Service" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" ExeCommand="[INSTALLFOLDER]Tango-DataBaseds.bat" Return="ignore" />
<CustomAction Id="UninstallService" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" ExeCommand="[INSTALLFOLDER]Remove_Baseds_Service.bat" Return="ignore" />
<InstallExecuteSequence>
<Custom Action="NssmUnzip" After="InstallFiles">NOT Installed</Custom>
<Custom Action="Tango_db" After="NssmUnzip">NOT Installed</Custom>
<Custom Action="Baseds_Service" After="Tango_db">NOT Installed</Custom>
<Custom Action="UninstallService" After="InstallInitialize"> Installed and Not REINSTALL</Custom>
</InstallExecuteSequence>
<Property Id="DIRR">
<RegistrySearch Id="aaa" Root="HKCU"
Key="Software\corp\Tango"
Name="Directory"
Type="directory"/>
</Property>
<Feature Id="ProductFeature" Title="DataBaseds_Service_Installer" Level="1">
<ComponentRef Id="MYSQL_Path"/>
<ComponentRef Id="MYSQL_USER"/>
<ComponentRef Id="MYSQL_PASSWORD"/>
<ComponentGroupRef Id="Components" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="DataBaseds_Service_Installer" />
</Directory>
</Directory>
<ComponentGroup Id="Components" Directory="INSTALLFOLDER">
<Component Id="NSSM" Guid="54CEB76C-6974-4071-96E9-EF5AD1937BD4">
<File Source="nssm-2.24.zip" KeyPath="yes" />
<File Source="Tango-DataBaseds.bat" KeyPath="no"/>
<File Source="Remove_Baseds_Service.bat" KeyPath="no"/>
<File Source="create-tangodb.bat" KeyPath="no"/>
</Component>
<Component Id="unzip" Guid="E10EE17A-AA5A-416B-82DF-37532281116C">
<File Source="unzip.exe" KeyPath="yes"/>
</Component>
</ComponentGroup>
<DirectoryRef Id="TARGETDIR">
<Component Id="MYSQL_USER" Guid="D05C8155-8421-4AEB-9A19-5016DAFAED19">
<Environment Id="MYSQL_USER" Name="MYSQL_USER" Value="root" Permanent="no" Part="last" Action="set" System="yes" />
</Component>
<Component Id="MYSQL_PASSWORD" Guid="222C7887-1E4D-4DC2-B429-A3F18F707FA3">
<Environment Id="MYSQL_PASSWORD" Name="MYSQL_PASSWORD" Value="tango" Permanent="no" Part="last" Action="set" System="yes" />
</Component>
<Component Id="MYSQL_Path" Guid="34D14695-1803-4D7E-AD65-3C9011D019CE">
<Environment Id="PATH" Name="PATH" Value="[DIRR]bin" Permanent="no" Part="last" Action="set" System="yes" />
</Component>
</DirectoryRef>
</Product>
</Wix>
Am I doing something wrong?
Greetings
There are two general issues with environment variables in Windows Installer:
When they are set they don't just automatically show up for running programs because Windows Installer doesn't send the "environment variables have changed" broadcast message until the end of the install. If you run a program AFTER that it will pick up the new values.
There is no reason for any running processes to pick them up unless they have a message loop and are prepared to deal with the (I think) WM_WININICHANGE message and reload the environment.
So none of your custom actions are going to pick up the new variables because they haven't been broadcast to the system yet and "committed". And yes, it's better to find another way to pass the data to the programs.
Phil is not wrong.
But here is my solution, if anyone will ever have the same problem:
Even though as Phil says: "system variables are not set during an installation:
Windows Installer doesn't send the environment variables have changed broadcast message until the end of the install, they are stored inside variable ( "DIRR" in this example) when you are reading the registry:
<Property Id="DIRR">
<RegistrySearch Id="aaa" Root="HKCU"
Key="Software\corp\Tango"
Name="Directory"
Type="directory"/>
</Property>
So you can run a script and pass them as argument:
<CustomAction Id="Tango_db" Directory="INSTALLFOLDER" Execute="deferred" Impersonate="no" ExeCommand="[INSTALLFOLDER]create-tangodb.bat ****"[DIRR]bin"****" Return="ignore" />
These way your batch file has access to the system variables, despite the fact that ther are not yet set in the system.
Hope that this helps :)

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>

Checking for .NET installed in WiX installer? Where to place the condition?

I need to check for .NET version 4.5 installed before proceeding with my installation. This is my .wxs file. I've placed the propertyref and condition under the tag. Why is this check is not working?
Even if .NET 4.5 is not present on the target system, the installation goes ahead anyway.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="SolidFire Hardware Provider"
Language="1033"
Version="1.0.0.0"
Manufacturer="SolidFire"
UpgradeCode="0c60967f-f184-4b8b-a96a-b1caa4a8879e">
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />
<!--Media Id='2' Cabinet='provider.cab' EmbedCab='yes'/-->
<PropertyRef Id="NETFRAMEWORK45"/>
<Condition Message="This application requires .NET Framework 4.5. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK45]]>
</Condition>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab='yes'/>
<Feature Id="ProductFeature" Title="InstallProvider" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!-- IRef Id="WixUI_Minimal"/-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" ></Property>
<!--Property WixUIDialogBmp = "logo.bmp"></Property-->
<UIRef Id="WixUI_InstallDir"/>
<InstallExecuteSequence>
<Custom Action="RunInstallScript" After="InstallFiles" >NOT Installed</Custom>
</InstallExecuteSequence>
<InstallExecuteSequence>
<Custom Action='BeforeUninstall' Before='RemoveFiles'>REMOVE="ALL"</Custom>
</InstallExecuteSequence>
<CustomAction Id="RunInstallScript"
ExeCommand="cmd /c install-solidfireprovider.cmd"
Directory="INSTALLFOLDER"
Execute="deferred"
Return="check"/>
<CustomAction Id="BeforeUninstall"
ExeCommand="cmd /c uninstall-solidfireprovider.cmd"
Directory="INSTALLFOLDER"
Execute="deferred"
Return="check"/>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="solidfireinstall" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent">
<!-- TODO: Insert files, registry keys, and other resources here. -->
<File Id="restinterfacedll.dll"
Source="..\vssprovider\x64\$(var.build)\RESTInterfacedll.dll"></File>
</Component>
<Component Id="vssdll">
<File Id="vsssolidfireprovider.dll"
Source="..\vssprovider\x64\$(var.build)\vsssolidfireprovider.dll"></File>
</Component>
<Component Id="installscript">
<File Id="installscript"
Source="install-solidfireprovider.cmd"></File>
</Component>
<Component Id="uninstallscript">
<File Id="uninstallscript"
Source="uninstall-solidfireprovider.cmd"></File>
</Component>
<Component Id="registerprovider">
<File Id="registerprovider"
Source="register_app.vbs"></File>
</Component>
<Component Id="vshadow">
<File Id="vshadow"
Source="vshadow.exe"></File>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
That looks OK so you probably also need to:
"Add the -ext command line parameter when calling light.exe to include the WixNetfxExtension in the MSI linking process."