Conditions within custom actions - wix

I recently separated our company installers in to two features (one enabled and one absent), to allow the user to select both, I've used UI_Mondo GUI to allow selection.
I've managed to get our custom action to work if the feature is selected:
<Custom Action="RestartIISForASPNet4" After="AspnetRegIIS"><![CDATA[(NOT INSTALLED) AND (&WebServiceFeature=3) AND NOT (!WebServiceFeature=3)]]></Custom
I tried but for some reason it's coming up with false (IMO, it can't as in the log the WixUI_InstallMode is set to InstallComplete.
<Custom Action="RestartIISForASPNet4" After="AspnetRegIIS"><![CDATA[((NOT INSTALLED) AND (&WebServiceFeature=3) AND NOT (!WebServiceFeature=3)) OR WixUI_InstallMode = "InstallComplete"]]></Custom>
Anybody have any ideas what I'm missing, it's probably really obvious.

WixUI_InstallMode is a private property. This means it uses its default value during InstallExecuteSequence (when your custom action runs).
A solution is to use custom action to save its value in a public property. You can then use that public property in your condition.
Public properties don't have lowercase letters in their names.

Related

How can I have a Modify/Change install run the XmlConfig action to accept new values (values from public properties)?

I have XmlConfig entries such as this:
<util:XmlConfig Id='SetSomething'
File="[WEBSITE]Web.config"
Action='create'
Node='value'
ElementPath="//configuration/appSettings/add[\[]#key='something'[\]]/#value"
Value="[SOMETHING]"
On='install'
PreserveModifiedDate='no'
VerifyPath="//configuration/appSettings/add[\[]#key='something'[\]]/#value"
/>
Which works fine on Install. However for Modify/Change installs, I prefer to allow the same UI dialog sequence so that they can change the values. 'change' without having to uninstall/reinstall.
Is it supposed to work this way - maybe by how it is scheduled? And if so, is it possible to change that? So far it looks like all of my properties are published in time during a Modify/Change, however the SchedXmlConfig action is confusingly different looking in the logs in a Modify/Change than in an Install

In InstallShield, how to change the value of my Property before it is used by SQL Text Replacement?

What I want to do
In InstallShield I want to set the value of a Property before it is used by the SQL Text Replacement feature. I want the new Property value to come from an Edit control that I've added to a dialog.
What I've done so far
I have added SQL Scripts to my InstallShield project, which include placeholders for InstallShield's Text Replacement feature. I've used the Text Replacement tab to find and replace a placeholder in the SQL script with the value of a Property that I've added to the Property Manager. This works correctly, but only for the Property's default value.
Where I'm stuck
The problem is that I want the new value to come from an Edit control in my custom Dialog, but I can't find a way to do this. Text Replacement always uses the Property's default value.
What I've tried is the following InstallScript, which runs when the user clicks Next on my custom Dialog:
CtrlGetText("MyDialog", EDIT_VALUE_FROM_USER, svValueFromUser);
MsiSetProperty ( hwndDlg, "EDIT_VALUE_FROM_USER", svValueFromUser);
Where EDIT_VALUE_FROM_USER is my Property. This runs without error, but the value doesn't come through to the final SQL script.
Why isn't the new value for EDIT_VALUE_FROM_USER being used by SQL Text Replacement? How can I diagnose why it's not working? Should I be doing this in a completely different way?
This turned out to be because I wasn't using the system property ISMSI_HANDLE.
So the correct code to write a Property from an Edit control in a custom dialog is:
CtrlGetText("MyDialog", EDIT_VALUE_FROM_USER, svValueFromUser);
MsiSetProperty (ISMSI_HANDLE, "EDIT_VALUE_FROM_USER", svValueFromUser);
I'm guessing your property isn't listed in the SecureCustomPublicProperties property and is getting set back to it's default value when the installer transitions to the install execute sequence. A log file of the installation would give more data to work with.

WiX default REFERENCED value OR Registry Value

I need to set a default database file for my application. I only want it to be set on initial installation. If the registry value--a string of the path to the sdf file--changes, then future upgrades should not try to set the value back to the default.
Another caveat, that seems to be a problem, though, is that if they've never setup a database file, the user should be able to use the program with a default database without having to go through setup.
So I set the DATABASEFILE with value="[INSTALLFOLDER]dust.sdf". but candle was complaining that [INSTALLFOLDER]:
The 'DATABASEFILE' Property contains '[INSTALLFOLDER]' in its value which is an illegal reference to another property. If this value is a string literal, not a property reference, please ignore this warning. To set a property with the value of another property, use a CustomAction with Property and Value attributes.
So, following the error's instructions, I added a custom action. Now that custom action ALWAYS overwrites the DATABASEFILE attribute. I want it to only override that value if the value doesn't exist in the registry.
Here's the code:
<CustomAction Id='SetINSTALLFOLDERREF' Property='DATABASEFILE' Value='[INSTALLFOLDER]dust.sdf' Execute='immediate' />
<Property Id='DATABASEFILE' >
<RegistrySearch Id='DatabaseFile' Type='raw' Root='HKCU' Key='Software\DBG\Dust\Database' Name='File'/>
</Property>
Have you set conditions on your custom action with Id=SetINSTALLFOLDERREF? If not, you might want to do it.
A condition of NOT DATABASEFILE on your custom action should probably suffice.
With the above condition,
-In the case of a fresh installation, the registry entry does not exist. Hence, DATABASEFILE is NULL, the custom action condition evaluates to true and the custom action SetINSTALLFOLDERREF executes.
-For any subsequent maintenance operations, the registry key is present, the property DATABASEFILE will always contain a value, the custom action condition evaluates to FALSE and the custom action will not be triggered.
Another thing you might want to do is to add the property DATABASEFILE to the list of SecureCustomProperties ie. secure the property DATABASEFILE.

Enabling / disabling Feature in custom action

I have a small setup project that contains 2 features, both published by default (Level = 1). In certain situations in custom action, I want to unpublish (set Level = 4) one of the features. Custom actions written in C#. How can I do that?
There are restrictions on where you can that, see the docs for the Condition table and doing this before CostFinalize:
https://msdn.microsoft.com/en-us/library/aa368014(v=vs.85).aspx
so assuming you have that under control, and you're early in the install then use a Feature condition. You already have a Feature element with level 1 by the sound of it, so add a condition that sets it to 4 when a property is set to something. In your code just set the property, and the level will change at CostFinalize.
Example:
Feature Id="FeatureX" Title="Feature X" Level="1"
<Condition Level="4"> <![CDATA[PROPVALUE=5]]> </Condition>

how to get the modified value of property after the feature is installed?

I have used a dialog in OnFirstUIBefore() for users to input some information,
and stored them in property USERINF.
However, when I want to retrieve the value of USERINF inputted by user in feature_installed(),
what I get is a default value.
I have added the USERINF to SecureCustomProperties property, but still cannot get the modified value.
How can I fix the problem?
I've always written values like these to the registry, then used appsearch to get them out into the property again.
There is no built in way to persist values like these built into MSI.