Setting property value in Wix - wix

I am trying to set a property to the installation directory. The following code doesnt work
<SetProperty Id="TALKMANSERVICE_MESSAGESCONFIG" Before="InstallInitialize" Value="[INSTALLDIR]\services\MessagesConfig.xml" />
So when can I set this property to the installation directory that has been selected by the customer?

Schedule it in the InstallExecuteSequence after CostFinalize. This is needed because you are using the value [INSTALLDIR] which is a directory table entry ( assuming it exists in your MSI and isn't called something else like INSTALLLOCATION ) and this entry won't be resolved to a property until after file costing.
Also, why do you need this property? You can use [#filekey] to have the installer tell you the full path to the file. See: Formatted
•If a substring of the form [#filekey] is found, it is replaced by the
full path of the file, with the value filekey used as a key into the
File table. The value of [#filekey] remains blank and is not replaced
by a path until the installer runs the CostInitialize action, FileCost
action, and CostFinalize action. The value of [#filekey] depends upon
the installation state of the component to which the file belongs. If
the component is run from the source, the value is the path to the
source location of the file. If the component is run locally, the
value is the path to the target location of the file after
installation. If the component has an action state of absent, the
installed state of the component is used to determine the [#filekey]
value. If the installed state of the component is also absent or null,
[#filekey] resolves to an empty string, otherwise it resolves to the
value based upon the component's installed state. For more information
about checking the installation state of components, see Checking the
Installation of Features, Components, Files.

Related

How to test if a parameter is passed into msi command line?

I am trying to install a msi file using msiexec on Windows. This msi can be installed either into the default ProgramFiles dir or a custom dir specified in the msiexec command.
For example when the custom dir is specified, the command looks like this:
msiexec /i installer_name.msi CUSTOM_DIR="C:\TEST" ALLUSERS=1
When CUSTOM_DIR is not specified then the command is
msiexec /i installer_name.msi ALLUSERS=1
For this to work, I am changing a Wix file and creating Custom Action and Custom Action Id.
When CUSTOM_DIR is passed by the installer, then
<Custom Action='InstallAppCustom' Before='InstallFinalize'>VersionNT64 and (CUSTOM_DIR) and (ALLUSERS=1)</Custom>
and when the CUSTOM_DIR is not passed then
<Custom Action='InstallApp' Before='InstallFinalize'>VersionNT64 and (Not CUSTOM_DIR) and (ALLUSERS=1)</Custom>
My questions are:
Is this the right way to check whether CUSTOM_DIR is passed or not? or any other right way to check it?
The issue here is that, irrespective of whether CUSTOM_DIR is passed or not, InstallAppCustom gets executed in the InstallExecuteSequence.
InstallAppCustom is getting executed everytime because CUSTOM_DIR will be always set. It must have initialized to some default value using Directory table. So, even if you didn't pass parameter, CUSTOM_DIR value will be set.
I understand why you want to check if parameter is passed from command-line but what if user changes CUSTOM_DIR value from UI? If it's not exposed to UI, then it's fine.
So, to check whether a property is passed from command-line, you need set property custom action which should be scheduled as very first action of InstallExecuteSequence, UISequence. Set property action will set CMD_CUSTOM_DIR property and its value would be [CUSTOM_DIR]. This should have condition of CUSTOM_DIR as at this point of installation time, default value of CUSTOM_DIR is not set. So, CMD_CUSTOM_DIR will always have cmdline value if passed and same can be used later on in other custom action conditions.
You can check the log msiexec /i yourmsi /l*v setup.log. There all cmd parameters and property changes and values are shown.
The above answer by Vivek helped me to solve the issue I had.
So I implemented something like:
<Property Id="DllPath32" Value="[ProgramFilesFolder]\App Name\dependencies"/>
<Property Id="DllPath64" Value="[ProgramFiles64Folder]\App Name\dependencies"/>
<!--CustomAction Id='SetDllPath64' Property='DllPath64' Value='[ProgramFiles64Folder]\\App Name' Return='check' /-->
<!--CustomAction Id='SetDllPath32' Property='DllPath32' Value='[ProgramFilesFolder]\\App Name' Return='check' /-->
<!--Custom Action='SetDllPath64' After='AppSearch'>VersionNT64</Custom-->
<!--Custom Action='SetDllPath32' After='AppSearch'>Not VersionNT64</Custom-->
The installation of the app worked as expected. Only issue is that, while uninstalling the app, the ProgramFiles64Folder is not changing to C:\Program Files.

WIX condition only on Install not working

I have the following within the Product Tag:
<Property Id="LICENSEKEY" Admin="yes" Hidden="no">
<RegistrySearch Id="RememberLicenseKey" Root="HKLM" Key="SOFTWARE\MyApp\key1\Settings" Name="LICENSEKEY" Type="raw"></RegistrySearch>
</Property>
<Condition Message="License key is required to proceed">LICENSEKEY AND NOT Installed</Condition>
What I want to do is pass the License key as a command line argument to msiexec, and then set it in the registry. If the key is not passed I want to cancel the installation. Therefore, this check only needs to be run at install time. However, the condition that I have added causes a popup both at install and uninstall time. Can't seem to figure out what I am doing wrong.
EDIT:
I tested with the following condition and it seems to show the message both on install and uninstall:
<Condition Message="License key is required to proceed">NOT Installed</Condition>
The Message for a Condition element will be displayed when the condition evaluates to false, meaning the condition was not met.
This is noted in the Message attribute description in the WiX Condition documentation:
Set the value to the text to display when the condition fails and the installation must be terminated.
To resolve this issue, the logical operators in the Condition just need to be changed to LICENSEKEY OR Installed
This is a late answer, but, hopefully, this will help any future visitors that find this question.
You may need to clarify your requirement. That WiX source does a search for the key, so does it need to be passed on command line or you'll cancel the install (as your post says), or can it be used if it's found in the registry by that registry search? Currently it appears that your registry search is overwriting anything you pass on the command line, including setting it to null, so check that with a verbose log.
Also, all the launch condition examples I've seen or used have a CDATA around the text of the actual condition - that may be part of the problem.
I'll assume you allow the key on the command line or in the registry. So your registry search should be for another property name, let's call it REGKEY, so it doesn't set your passed LICENSEKEY to null. Then you have a set property (type 51) custom action immediately after the search that sets LICENSEKEY to REGKEY with a condition of -Not LICENSEKEY- so it will set LICENSEKEY to REGKEY only if LICENSEKEY was not passed on the command line. So if you pass it on the command line it will be used, otherwise the registry one will be used. At that point, a condition of LICENSEKEY should work ok as a launch condition. Internally, the AppSearch that finds the registry item is typically immediately followed by the launch condition check in a WiX MSI, so you need to set LICENSEKEY before the launch condition check.

How to reference SystemFolder in WiX Icon.SourceFile property?

To make the long story short, this doesn't work:
<Icon Id="msiexec.ico" SourceFile="[SystemFolder]msiexec.exe"/>
(Error 4 The system cannot find the file '[SystemFolder]msiexec.exe')
And this doesn't work too:
<Icon Id="msiexec.ico" SourceFile="$(var.SystemFolder)msiexec.exe"/>
Error 3 Undefined preprocessor variable '$(var.SystemFolder)'.
The second sample in your question will work if you pass var.SystemFolder as a parameter to candle.exe.
The <Icon> element is mapped to the Icon MSI table. At build time it tries to find the path you specify in SourceFile attribute and stream it as binary data to the Data column of the Icon table. This means, the path should be known at build time. But this is not true in your first sample - SystemFolder is resolved at install time.

session.CustomActionData is empty in repair

I have one custom action that is executed all the time (doesn't have any condition).
This custom action is "deferred" and get correctly the value on fresh install or upgrade, but in repair mode the value passed is empty.
In setup log the value is shown with correctly, but in custom action the value is ''.
Is correct that in repair the value to be always null?

WIX MSI - PROPERTY override precedence

Any help will be much appreciated.
I'm writing this WIX installer to get an MSI to install a web app on our servers.
Within my app, I have this PROPERTY - "WEBDIR". I use this property later in my code as a Directory Id.
I set this property in 3 ways.
(Method 'A') As a property passed when you call msiexec in quiet mode. [Setting it here as C:\Path1] Like so:
msiexec /quiet /i My.msi WEBDIR="C:\Path1" /l*v InstallationLog.log
(Method 'B') From an IniFileSearch. I have an ini file in C:\Windows called MySetup.ini where the key WebsitesDir resolves the value C:\Path2. [Setting it here as C:\Path2]:
<Property Id="WEBDIR">
<IniFileSearch Id="WebsitesDirIni" Name="MySetup.ini" Section="InstallLocations" Key="WebsitesDir" Type="raw"/>
</Property>
(Method 'C') Using a default directory structure. [Setting it here as C:\Path3] As follows:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="WEBDIR" Name="Path3">
</Directory>
</Directory>
The way it currently works is as follows:
- When Methods 'A', 'B' and 'C' all set the property value, B takes precedence.
- When only Methods 'A' and 'C' set the property value, 'C' takes precedence.
What I want is to be able to set the order of precedence to 'A'. If !'A' then 'B' else 'C'.
Is this possible?
No, this is not possible. If you want to control the order the best approach would be an immediate custom action. Since it needs to set an installer property, your custom action must receive the installation handle (a win32 DLL is recommended).
Under normal circumstances the installer will use this order:
A command line value initializes the property
A directory row sets the initial folder path, overriding the command line value. This path can be later modified by costing actions (CostFinalize).
A search overrides the initial folder path, but may be overridden by costing actions.