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

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.

Related

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.

Setting property value in 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.

Error Getting Property

So.. I've got this CA
<CustomAction Id="InstallSetProp" Property="CustomActionData" Value="<some other data that's formatted exactly the same> /webconftmploc="[WEBCONFIGTMPLOC]"" />
However, when this CA is called, a message box is shown saying "Error Getting Property" which is bogus since the property is correctly set and accessible later on. (And does nothing except mess up my attempts to fully automate installation) I'm running the .msi through a bootstrapper that switches /qr to help with this.
The message box error is not shown when /webconftmploc="[WEBCONFIGTMPLOC]" is removed, for the record [WEBCONFIGTMPLOC] is either an absolute file path or "Not Set" and I'm wondering if there's any special reason why this behaviour can occur.
However, I'm much more interested in any possible way to suppress or fix this action, of-course.
That CustomAction only sets a property. It is not possible for it to show an error message. If any of the properties were not defined they would just resolve to blank. Something else must be showing the error message.
However, it appears that you are trying to pass data to a deferred custom action due to your use of the specially named CustomActionData. That isn't quite the way to use CustomActionData though. Instead, the Property attribute should be set to the Id of the CustomAction that you want to pass data too. Say the custom action that uses that property value is something like:
<CustomAction Id='MyDeferredCustomAction' Execute='deferred' ... />
To pass it the string you are trying to send, you could write:
<CustomAction Id="InstallSetProp"
Property="MyDeferredCustomAction"
Value="<some other data that's formatted exactly the same> /webconftmploc="[WEBCONFIGTMPLOC]"" />
Notice that the second custom action is setting a property with the same name as the deferred custom action: MyDeferredCustomAction. The MyDeferredCustomAction can access the value <some other data that's formatted exactly the same> /webconftmploc="value_of_WEBCONFIGIMPLOC_goes_here" via the magical CustomActionData property. You can read more about that here: http://msdn.microsoft.com/en-US/library/2w2fhwzz(v=VS.80).aspx

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.