Override Publish within UIRef in WiX - wix

I have an UI library with this code:
<Fragment>
<UI Id="My_UI">
<Dialog Id="Dialog_A">
<Control Id="Button_Next" Type="PushButton" Text="Next">
<Publish ... />
</Control>
</Dialog>
</UI>
</Fragment>
And then I have my main project with a reference to this library.
<Product>
<UIRef Id="My_UI" />
</Product>
The problem is that I cannot add a new Publish event. I tried to do this, but then it doesn't work at all.
<Product>
<UI Id="My_UI">
<DialogRef Id="Dialog_A" />
<Publish Dialog="Dialog_A" Control="Button_Next"
Event="DoAction" Value="GenInstallReview">1</Publish>
</UI>
</Product>
How can I extend the dialog with a new Publish in the main application?

You can add control events but you cannot override existing ones. Open your .msi with Orca and inspect the ControlEvent table rows for Dialog_A. When you have multiple rows for the same dialog/button combination, you have to follow the rules specified here.

Related

Conditional Feature based on Property

In my bundle I have 2 features which both are about creating a folder structure based on the value of a property. As you can see my conditions are fairly simple. What is interesting is that only the condition on feature ONE works, while in feature TWO (where it does a comparison) it does nothing, but If I add the condition on every component I need just like in the other pasted code it works fine.
I was wondering why this is happening
<Property Id="NUMBER" />
<Feature Id="ONE" Level="0">
<Condition Level="1">
<![CDATA[NOT NUMBER]]>
</Condition>
<ComponentGroupRef Id="OneStructure"/>
</Feature>
<Feature Id="TWO" Level="0">
<Condition Level="1">
<![CDATA[NUMBER <> ""]]>
</Condition>
<ComponentGroupRef Id="OneStructure"/>
</Feature>
-
<Directory Id="dir77996843FCCE5E3734A5EDAA86FCE55B" Name="Input">
<Component Id="cmp2F4C23D858A887EF0B2539F7EC1884BE" Guid="{625D2714-157F-4B21-86C0-D4954A4E1F73}" KeyPath="yes"> <Condition> <![CDATA[NUMBER <> ""]]> </Condition>
<CreateFolder />
</Component>
</Directory>
Had the same issue. Apparently it has to do with the condition only being evaluated once.
Instead of putting a condition directly in a feature, you can put conditions in a Control Event pertaining to a button in a given dialog.
Example:
<Control Id="Install" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Text="Install">
<!--Check property value here:-->
<Publish Event="AddLocal" Value="ALL">1</Publish>
<Publish Event="Remove" Value="ONE">NUMBER = 0</Publish>
<Publish Event="Remove" Value="TWO">NUMBER = 1</Publish>
<Publish Event="EndDialog" Value="Return" />
</Control>
You would then change the value of the property "NUMBER" with a Radio Button.
Hope this helps!

How to display a dialog box with warning message in Wix installer?

I need to display a warning message while running my installer if a firefox maintenance service is installed.
To achieve this, I added a registry search property, and then added the code for dialog box in wix:
<Property Id="MAINTENANCESERVICEINSTALLED">
<RegistrySearch Id="MSID" Root="HKLM" Key="SOFTWARE\Mozilla\MaintenanceService" Name="Installed" Type="raw"/>
</Property>
<UI>
<Dialog Id="MaintenanceServiceWarningDialog" Width="284" Height="73" Title="Warning" NoMinimize="yes">
<Control Id="Text" Type="Text" X="38" Y="8" Width="240" Height="40" TabSkip="no">
<Text>Firefox Maintenance is installed on your system. Disable it to prevent compatibility issues. Click OK to proceed.</Text>
</Control>
<Control Id="OK" Type="PushButton" X="114" Y="52" Width="56" Height="17" Default="yes" Cancel="yes" Text="OK">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
</Dialog>
<InstallUISequence>
<Show Dialog="MaintenanceServiceWarningDialog" Sequence="1"> <![CDATA[NOT Installed AND MAINTENANCESERVICEINSTALLED]]></Show>
</InstallUISequence>
</UI>
I am using to show the dialog box. The above code is under "Product" tag.
I am getting build issues with this like below. And when I move the UI code to Fragment, the installer does not display anything. Not sure what's wrong.
Your InstallUISequence element is inside the UI element.

Wix - Unresolved reference to custom dialog

In my installer I try to launch a windows program on which the user has to perform some actions in parallel to the page giving the instructions. For this I added a new page (as per this tutorial). Now I want to start a custom action before this new dialog but I get the following error:
error LGHT0094 : Unresolved reference to symbol 'WixAction:InstallUISequence/UserRegistrationDlg' in section 'Product:*'.
Minimal example:
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='Foobar 1.0' Id='*' Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='Acme Ltd.'>
<Package InstallerVersion='300' Compressed='yes' />
<Directory Id='TARGETDIR' Name='SourceDir'/>
<UI Id="MyWixUI_FeatureTree">
<DialogRef Id="TheNewDialog" />
<UIRef Id="WixUI_FeatureTree" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="TheNewDialog" Order="2">LicenseAccepted = "1"</Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="TheNewDialog">1</Publish>
</UI>
<CustomAction Id="WindowsFeatures" Directory="TARGETDIR" ExeCommand="OptionalFeatures.exe" Execute="immediate" Return="asyncNoWait" />
<InstallUISequence>
<Custom Action="WindowsFeatures" After="TheNewDialog" >
NOT Installed AND NOT DOTNETINSTALLED
</Custom>
</InstallUISequence>
</Product>
<Fragment>
<UI>
<Dialog Id="TheNewDialog" Width="370" Height="270" Title="[ProductName] [Setup]" NoMinimize="yes">
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>
I tried to instead of Before="TheNewDialog", set it to After="WelcomeDlg" but that gives even more interesting errors:
error LGHT0094 : Unresolved reference to symbol 'Property:ApplicationFolderName' in section 'Fragment:'.
error LGHT0094 : Unresolved reference to symbol 'Property:WixAppFolder' in section 'Fragment:'.
I have been looking around and this seems to be related to WixUI_Advanced but I have no idea how I am triggering Wix to think I am using that.
I have the feeling I am doing something silly with referencing wrong but I can't seem to get my fingers on the right way so I hope somebody can tell me how to get this working.
it is necessary to add WixUIExtension.dll instead of WixUtilExtension.dll
Of course, while cleaning up all the search tabs I came across something that solved it and then realised some details.
The problem is that my new dialog is not in the 'InstallUISequence' but part of the flow on WelcomeDlg's sequence number. Therefore it can't be referenced in a before/after.
The solution to this is to not try to set the custom even in the 'InstallUISequence' but put it in a publish of the button going towards the new page like this on the button description itself:
<Publish Event="DoAction" Value="WindowsFeatures">1</Publish>
or like this when adding it later from a UI block
<Publish Dialog="WelcomeDlg" Control="Next" Event="DoAction" Value="WindowsFeatures" >1</Publish>
I still don't get the 'WixUI_Advanced' getting dragged into the story though.
add reference to C:\Program Files (x86)\WiX Toolset v3.10\bin\WixUtilExtension.dll

Set property in custom dialog for conditional feature

I have a property called SELECTEDFEATURESET with a default value of 'none'. In a custom dialog I'm trying to set this property, according to which button the user pressed. At the end I use the property to decide if certain components shall be installed or not.
Propery defined in the main installer file (Product.wxs):
<Property Id='SELECTEDFEATURESET' Value='none' />
Set the property in the dialog:
<Control Id="InternalFeatureButton" Type="PushButton" Text="FeatureSetA">
<Publish Event="NewDialog" Value="InstallDirDlg">1</Publish>
<Publish Property="SELECTEDFEATURESET" Value="FeatureSetA">1</Publish>
</Control>
<Control Id="ProductionFeatureButton" Type="PushButton" Text="FeatureSetB">
<Publish Event="NewDialog" Value="InstallDirDlg">1</Publish>
<Publish Property="SELECTEDFEATURESET" Value="FeatureSetB">1</Publish>
</Control>
<Control Id="DemoFeatureButton" Type="PushButton" Text="FeatureSetC">
<Publish Event="NewDialog" Value="InstallDirDlg">1</Publish>
<Publish Property="SELECTEDFEATURESET" Value="FeatureSetC">1</Publish>
</Control>
Decide whether the feature shall be installed or not:
<Feature Id='ParentFeature' Level='0'>
<ComponentRef Id='ComponentA' />
<Condition Level='1'><![CDATA[SELECTEDFEATURESET="FeatureSetA"]]></Condition>
</Feature>
<Feature Id='ParentFeature' Level='0'>
<ComponentRef Id='ComponentB' />
<Condition Level='1'><![CDATA[SELECTEDFEATURESET="FeatureSetB"]]></Condition>
</Feature>
<Feature Id='ParentFeature' Level='0'>
<ComponentRef Id='ComponentC' />
<Condition Level='1'><![CDATA[SELECTEDFEATURESET="FeatureSetC"]]></Condition>
</Feature>
When I run the installer and press the FeatureSetA button, no optional component is installed. When I initialize the SELECTEDFEATURESET property with 'FeatureSetA', then the ComponentA is installed (same for A, B and C).
Why is the value of SELECTEDFEATURESET 'none' instead of 'FeatureSetA' / 'FeatureSetB' / 'FeatureSetC' at the time of the feature condition evaluation?
How do I fix it?
I fixed it my moving the condition from the feature to the component.

Inserting Custom Action between Dialogs (InstallUISequence) in WiX

I have two custom dialog boxes (plus the required ones ExitDlg, FatalErrorDlg, etc.), the first one sets a property using an Edit control and the second one shows this property using a Text control. Here is the meaningful code:
<Dialog Id="DialogA" ...>
<Control Id="ControlEdit" Type="Edit" Property="MY_PROPERTY" .../>
<Control Id="ControlNext" Type="PushButton" ...>
<Publish Event="EndDialog" Value="Return" /></Control>
</Dialog>
And then the second dialog:
<Dialog Id="DialogB" ...>
<Control Id="ControlText" Type="Text" Text="[MY_PROPERTY]" .../>
<Control Id="ControlBack" Type="PushButton" ...>
<Publish Event="EndDialog" Value="Return" /></Control>
<Control Id="ControlNext" Type="PushButton" ...>
<Publish Event="EndDialog" Value="Return" /></Control>
</Dialog>
And the action sequence:
<InstallUISequence>
<Show Dialog="DialogA" Before="MyCustomAction" />
<Custom Action="MyCustomAction" Before="DialogB" />
<Show Dialog="DialogB" Before="ExecuteAction" />
</InstallUISequence>
The custom action changes the value of MY_PROPERTY. My problem is how to make the Back button in DialogBget back to DialogA. Using NewDialog is simple, but then I can't get the custom action to be executed between the dialogs, or can I?
edit - 2013-05-02
After the answer from #caveman_dick, I tried to change the DialogA almost like he said, but instead of using EndDialog, I changed to Action="NewDialog" Value="DialogB". But now the Custom Action isn't being called. If I remove the Publish event to go to next dialog, then the CA is called. If I leave as #caveman_dick said, I can't get back to DialogA from DialogB.
edit - 2013-05-02
After searching in book WiX 3.6: A Developer's Guide to Windows Installer XML, I found the following: "if you have more than one Publish event, they must have conditional statements as their inner text. Otherwise, all of the events simply won't be published."
So the answer from #caveman_dick is correct, except that you need to change to the following:
<Publish ...>1</Publish>
Rather than scheduling the custom action in the InstallUISequence you can publish it on the button click:
<Dialog Id="DialogA" ...>
<Control Id="ControlEdit" Type="Edit" Property="MY_PROPERTY" .../>
<Control Id="ControlNext" Type="PushButton" ...>
<Publish Event="DoAction" Value="MyCustomAction">1</Publish>
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
</Dialog>
EDIT: The Publish element's condition needs to explicitly evaluate to true to run, so add "1" as the text of the Publish elements.