Using a WiX property from a browse dialog - wix

I'm developing a setup project using WiX, and I have the following problem. I get a directory path from the user using the Browse dialog, and I need to put this path in web.config. The problem is that in web.config that puts the value in "WWWMain" and not the path chosen by the user.
This is my code:
Product.wxs
<Property Id="IISLOGDIRECTORY" Value="WWWMain" />
Dialog.wxs
<Control Id="IISLogDirectoryEdit" Type="PathEdit" X="45" Y="100" Width="220" Height="18" Disabled="yes" Property="IISLOGDIRECTORY" Indirect="yes" />
Installation.wxs
<util:XmlFile Id="ModifyIISLogDirectory"
Action="setValue"
Permanent="yes"
ElementPath="/configuration/appSettings/add[\[]#key='isslogdirectory'[\]]/#value"
File="[INSTALLLOCATION]Web\Web.config"
Value="[IISLOGDIRECTORY]"/>

Declare the variable in Dialog.wxs itself but after the control
Example
<Control Id="DiffBackUpEdit" Type="PathEdit" X="120" Y="157" Width="160" Height="18" Property="IISLOGDIRECTORY">
</Control>
<Control Id="Browse12" Type="PushButton" X="290" Y="157" Width="56" Height="17" Text="Browse">
<Publish Property="_BrowseProperty" Value="DIFFDBBACKUPLOC" Order="1">1</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
</Control>
Then at bottom in same page after add
<Property Id="IISLOGDIRECTORY" Value="C:\Database\MDM"/>

Related

Wix Custom Action Property Not Immediately Available

I have a Wix VBScript Custom Action that sets a Property, and then a publish event that is supposed to trigger based on the value of the set property. The issue seems to be that the property is not being set and in turn not triggering the next publish event. Has anyone successfully done something similar?
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:hsi="http://schemas.hyland.com/wix/UtilityExtension">
<Fragment>
<Property Id="FOO" Value="0" Secure="yes" />
<CustomAction Id="Test3" Script="vbscript">
<![CDATA[
MsgBox Session.Property("FOO")
]]>
</CustomAction>
<CustomAction Id="Test2" Script="vbscript">
<![CDATA[
MsgBox "Test"
]]>
</CustomAction>
<CustomAction Id="Test1" Script="vbscript">
<![CDATA[
Session.Property("FOO") = "1"
]]>
</CustomAction>
</Fragment>
<Fragment>
<UI>
<DialogRef Id="WarningModalDlg"/>
<Dialog Id="BaseLawsonWebServerDlg" Width="370" Height="270" Title="Lawson LOB Broker Relay Setup">
<Control Id="label" Type="Text" X="20" Y="50" Width="200" Height="16" Text="Test" TabSkip="yes" Transparent="yes" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Publish Order="1" Event="DoAction" Value="Test3">1</Publish>
<Publish Order="2" Event="DoAction" Value="Test2">FOO = "1"</Publish>
<Publish Order="3" Event="DoAction" Value="Test1">1</Publish>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)"/>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>
Event="DoAction" Value="Test1" fires, I've tested it. Event="DoAction" Value="Test2">FOO = "1" does not hit. Then Event="DoAction" Value="Test3">1</Publish> definitely hits and shows the message box with the default value.
Thanks ahead of time!
I figured it out! I was so used to the reverse order of UI Dialog Publish events that I did the same thing for Control publish events.
Control Publish events move in the the order of 1 to x.
The publish events should look like this instead:
<Publish Order="1" Event="DoAction" Value="Test1">1</Publish>
<Publish Order="2" Event="DoAction" Value="Test2">FOO = "1"</Publish>
<Publish Order="3" Event="DoAction" Value="Test3">1</Publish>

Using a condition to make changes to the Windows firewall in WIX

I am trying to make changes to the Windows firewall based on a property that is set in a dialog. I can see in the log that the property is being set correctly but the firewall rules are being created regardless of the value of the property.
My code is...
<Component Id="ChangeFirewall" Guid="*" KeyPath="yes">
<Condition><![CDATA[ChgFirewall = "True"]]></Condition>
<fire:FirewallException Id="FW6501" Name="6501" Port="6501"
Protocol="tcp" Scope="any"/>
<fire:FirewallException Id="FW6502" Name="6502" Port="6502"
Protocol="tcp" Scope="any"/>
<fire:FirewallException Id="FW6505" Name="6505" Port="6505"
Protocol="tcp" Scope="any"/>
</Component>
If ChgFirewall is False why does the firewall get changed?
Update: I have added the code for the dialog that sets the CHGFIREWALL property...
<Dialog Id="FirewallDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="Description" Type="Text" X="20" Y="20" Width="280" Height="40" Transparent="yes" NoPrefix="yes">
<Text>This program uses TCP ports 6501, 6501, and 6505 for coordinating information between workstations. These ports must be unblocked for it to work correctly</Text>
</Control>
<Control Id="Instructions" Type="Text" X="20" Y="70" Width="280" Height="30" Transparent="yes" NoPrefix="yes">
<Text>This installer can attempt to automatically modify the Windows Firewall for you, or you may manually modify the firewall settings.</Text>
</Control>
<Control Type="RadioButtonGroup" Property="CHGFIREWALL" Id="CHGFIREWALL" Width="340" Height="44" X="20" Y="120">
<RadioButtonGroup Property="CHGFIREWALL">
<RadioButton Text="Have the installer update the firewwall settings for Guru (Recommended)" Height="13" Value="True" Width="340" X="0" Y="0" />
<RadioButton Text="Manually update the firewall settings" Height="13" Value="False" Width="340" X="0" Y="15" />
</RadioButtonGroup>
</Control>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="Next">
<Publish Event="EndDialog" Value="Return"></Publish>
</Control>
<Control Id="CancelButton" Type="PushButton" Text="Cancel" Height="17" Width="56" X="180" Y="243" Cancel="yes">
<Publish Event="EndDialog" Value="Exit" />
</Control>
</Dialog>
Also this is my definition of the property...
<Property Id='CHGFIREWALL' Value='False' Secure='yes'/>
As a first step, UPPERCASE the property and set the attribute 'secure="yes". This ensures that the property is passed properly to the server process as explained in the comments here.
Then the issue is how you set the property? Is is set by a custom action, or do you set it in the Property table or on the command line?

WIX UI Property Change Not Publishing

I have a edit control in WIXUI that's bound to a property
<Property Id="WIXUI_FILESHAREDIR">FILESHAREDIR</Property>
and the UI
<Control Id="FileSharePathGroup" Type="GroupBox" Height="89" Width="352" X="8" Y="96" Text="File Share"/>
<Control Id="FileSharePathLabel" Type="Text" X="20" Y="114" Width="69" Height="13" Text="File Share Path"/>
<Control Id="FileSharePathEdit" Type="PathEdit" X="20" Y="126" Width="250" Height="16" Property="WIXUI_FILESHAREDIR" Indirect="yes" />
<Control Id="FileSharePathBrowse" Type="PushButton" X="280" Y="125" Width="56" Height="17" Text="Browse"/>
and the following Publish statements:
<Publish Dialog="ConfigurationDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg">1</Publish>
<Publish Dialog="ConfigurationDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="ConfigurationDlg" Control="FileSharePathBrowse" Property="_BrowseProperty" Value="[WIXUI_FILESHAREDIR]" Order="1">1</Publish>
<Publish Dialog="ConfigurationDlg" Control="FileSharePathBrowse" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
When I use the browse button the FILESHAREDIR property ends up getting updated correctly. When I type into the text editor manually and hit Next, it doesn't and the FILESHAREDIR retains the incorrect default value at install time.
Am I missing a Publish statement?
You need to use the Property#Secure attribute to list the public property in the SecureCustomProperties property.

Checking on the click of next button whether the user has entered a value in textbox

I want to know how do I validate the entry in the textbox? I am making use of the wix toolset 3.5. What I mean is I should get a prompt or some message that says that you must enter the text (I have a name of the person here ) and the installation must not proceed without it.
You need to modify your UI element so that there is a conditional Publish tag that determines if the property attached to the TextBox is populated or not:
<Publish Dialog="NameSettingsDlg"
Control="Next"
Property="ErrorMessage" Value="You need to fill in your name!"
Order="1">
NOT NAME_PROPERTY
</Publish>
<Publish Dialog="NameSettingsDlg"
Control="Next"
Event="SpawnDialog"
Value="InvalidSettingsDlg"
Order="2">
NOT NAME_PROPERTY
</Publish>
<Publish Dialog="NameSettingsDlg"
Control="Next"
Event="NewDialog"
Value="VerifyReadyDlg">
</Publish>
where the "InvalidSettingsDlg" is defined as:
<Fragment>
<UI>
<Dialog Id="InvalidSettingsDlg"
Width="260"
Height="85"
Title="!(loc.InvalidSettingsDlg_Title)">
<Control Id="OK" Type="PushButton" X="102" Y="57" Width="56"
Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIOK)">
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
<Control Id="Text" Type="Text" X="48" Y="22" Width="194" Height="30"
Text="[ErrorMessage]" />
<Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24"
ToolTip="!(loc.InvalidSettingsDlgIconTooltip)" FixedSize="yes"
IconSize="32" Text="WixUI_Ico_Exclam" />
</Dialog>
</UI>
</Fragment>

Use WiX browser dialog to set edit box value

I'm trying to create a WiX installer dialog that provides a series of textboxes that users need to fill in with directory locations.
What I would like to do is put a Browse button next to each dialog and when they click it, the WiX Browse dialog will come up, they select a file location, click OK, and the text box next to the browse button will be filled in.
I know how to do it with a custom action, but I was wondering if there was a pure WiX way of doing this.
EDIT: I should be more clear. I meant directory locations, not file locations. Wix doesn't have file browsing support as one user indicated below.
I found a way to do it completely in WiX. WiX comes with a browse dialog called BrowseDlg. Here's what I did:
I created a dialog that includes a PathEdit control and PushButton control. Notice that the PathEdit control has the Indirect property set to yes. This means that whatever you set Property to is just a pointer to something else.
<Dialog Id="BackupConfigDlg" Width="370" Height="270" Title="Backup Configuration">
<Control Type="Text" Id="lblInstructions" Width="348" Height="13" X="10" Y="10">
<Text>{\WixUI_Font_Title}Please select the directory you want to backup.</Text>
</Control>
<Control Type="Text" Id="lblBackupDirectory" Width="69" Height="9" X="10" Y="40" Text="Backup directory:">
</Control>
<Control Type="PathEdit" Id="Folder" Width="219" Height="15" X="82" Y="38" Property="_BrowseProperty" Indirect="yes" />
<Control Type="PushButton" Id="Browse" Width="56" Height="17" X="304" Y="37" Text="Browse..." />
<Control Type="Line" Id="line" Width="362" Height="2" X="4" Y="229" />
<Control Id="Cancel" Type="PushButton" X="239" Y="240" Width="56" Height="17" Cancel="yes" Text="Cancel">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Type="PushButton" Id="Install" Width="56" Height="17" X="300" Y="240" Text="Install">
<Publish Event="EndDialog" Value="Return" />
</Control>
</Dialog>
The browse dialog (that we'll eventually get to) expects to set an object in the Directory table, so we need to create a Directory object that will only be used to hold the value we browse to. Since we won't put any components in it, nothing on the file system will change relating to the directory we choose. I call mine TARGETBACKUPDIRECTORY.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="TARGETBACKUPDIRECTORY">
</Directory>
...
</Directory>
Now we need to create a property that points to the Directory object.
<Property Id="BACKUPDIRECTORY" Value="TARGETBACKUPDIRECTORY" />
We now need to make sure that the _BrowserProperty property is properly bound to BACKUPDIRECTORY (because it points to the Directory object we want set) before this dialog opens. If you don't, you will get an error during the install process when you attempt to open the dialog. In my example, PrevDlg is a dialog that appears before BackupConfigDlg. What's happening here is that when the Next button is pushed, I set the _BrowserProperty property to BACKUPDIRECTORY, I then open the dialog. It must take place in that order so I use the Order property to enforce it. I do the same thing when the browse button is pushed, not sure I need to do, but I do it just for safe measure.
<Publish Dialog="PrevDlg" Control="Next" Property="_BrowseProperty" Value="[BACKUPDIRECTORY]" Order="1">1</Publish>
<Publish Dialog="PrevDlg" Control="Next" Event="NewDialog" Value="BackupConfigDlg" Order="2">1</Publish>
<Publish Dialog="BackupConfigDlg" Control="Browse" Property="_BrowseProperty" Value="[BACKUPDIRECTORY]" Order="1">
</Publish>
<Publish Dialog="BackupConfigDlg" Control="Browse" Event="SpawnDialog" Value="BrowseDlg" Order="2">
</Publish>
That's what worked for me.
The selected answer to this question is way too much work. You don't need to do all that.
Set your PathEdit control to the directory to configure as you normally would. Then, in the actions of the browse button, set _BrowseProperty to the NAME (not value of) of your property to configure and then SpawnDialog. That's it.
<Control Type="PathEdit"
Id="TxtDir"
Width="155" Height="15"
X="105" Y="57"
Property="OUTPUTDIRECTORY"/>
<Control Id="btnDirBrowse"
Type="PushButton"
Width="56" Height="17"
X="260" Y="57"
Text="Browse..." >
<Publish Property="_BrowseProperty" Value="OUTPUTDIRECTORY" Order="1">1</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
</Control>
In order to have multiple directories (filled by the BrowseDlg) in the same dialog window, an extra indirection is required. Notice also the numbering within the <Publish></Publish> tags :
<Control Id="WorkingDirFolderLabel" Type="Text" Width="220" Height="12" X="10" Y="50" Text="Working directory:"/>
<Control Id="WorkingDirFolder" Type="PathEdit" Width="250" Height="17" X="10" Y="62" Property="_WorkingDirBrowseProperty" Indirect="yes"/>
<Control Id="WorkingDirBrowse" Type="PushButton" Width="56" Height="17" X="265" Y="62" Text="Browse..." >
<Publish Property="_BrowseProperty" Value="[_WorkingDirBrowseProperty]" Order="2">1</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="3">1</Publish>
</Control>
<Control Id="DocsDirFolderLabel" Type="Text" Width="220" Height="12" X="10" Y="100" Text="Documentation area:"/>
<Control Id="DocsDirFolder" Type="PathEdit" Width="250" Height="17" X="10" Y="112" Property="_DocsDirBrowseProperty" Indirect="yes" />
<Control Id="DocsDirBrowse" Type="PushButton" Width="56" Height="17" X="265" Y="112" Text="Browse..." >
<Publish Property="_BrowseProperty" Value="[_DocsDirBrowseProperty]" Order="2">2</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="3">2</Publish>
</Control>
Then pass the references as before (no need to define extra properties) :
<Publish Dialog="PrevDlg" Control="Next" Property="_WorkingDirBrowseProperty" Value="TARGETWORKINGDIRECTORY" Order="1">1</Publish>
<Publish Dialog="PrevDlg" Control="Next" Property="_DocsDirBrowseProperty" Value="TARGETDOCSDIRECTORY" Order="1">1</Publish>
<Publish Dialog="PrevDlg" Control="Next" Event="NewDialog" Value="BackupConfigDlg" Order="2">1</Publish>
Windows Installer doesn't support file browsing, so there is no direct support for this in WiX. The best solution is still a custom action executed when clicking browse button.
You can find a sample custom action here: http://www.installsite.org/pages/en/msi/ca.htm
None of the above or anywhere else worked for me. What did work is so more simple and straight forward.
Like many, I need to prompt the Installer user for the target locations of SQL Server .mdf and .ldf files, which will likely reside outside of any pre-installation Directory structure. In fact, my preceding Dialog prompts the user for the target database server. Given that, I then custom act on that preceding Dialog's "Next" button to (a) find the mdf & ldf paths of the server's "master" database and then (b) default the new database's respective paths to those of the master db.
But hours of frustration making PathEdit play nice with BrowseDlg proved futile. What I ended up doing was creating a placeholder Property called PATH_TEMP_BROWSE. It is the "SetTarget" call in the BrowseDlg that forces us to enlist the Wix Directory tree. Get rid of that line in your own custom rip-off of BrowseDlg and instead pass around the user's selected directory via PATH_TEMP_BROWSE thusly:
<Dialog Id="DirectoryBrowserDlg" Width="370" Height="270" Title="Dir Browse">
<Control Id="Path" Type="PathEdit" X="25" Y="202" Width="320" Height="18" Property="PATH_TEMP_BROWSE" Indirect="yes" />
<Control Id="OK" Type="PushButton" X="240" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUIOK)">
<!-- NO! -->
<!--<Publish Event="SetTargetPath" Value="[_BrowseProperty]">1</Publish>-->
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>
...
<Control Id="DirectoryCombo" Type="DirectoryCombo" X="70" Y="55" Width="220" Height="80" Property="PATH_TEMP_BROWSE" Indirect="yes" Fixed="yes" Remote="yes">
<Subscribe Event="IgnoreChange" Attribute="IgnoreChange" />
</Control>
...
<Control Id="DirectoryList" Type="DirectoryList" X="25" Y="83" Width="320" Height="98" Property="PATH_TEMP_BROWSE" Sunken="yes" Indirect="yes" TabSkip="no" />
...
</Dialog>
Then, to make use of my pop-up modal DirectoryBrowserDlg within my installation Dialog that prompts the user for the new database name as well as its logical files...
<Control Id="MdfPath"
Type="PathEdit"
X="37"
Y="184"
Width="313"
Height="18"
Property="PATH_DBMDFCS"
/>
<Control Id="MdfBrowse"
Type="PushButton"
X="350"
Y="184"
Width="22"
Height="17"
Text="Browse..."
>
<Publish Property="PATH_TEMP_BROWSE" Value="PATH_DBMDFCS" Order="1">1</Publish>
<Publish Event="SpawnDialog" Value="DirectoryBrowserDlg" Order="2">1</Publish>
<Publish Property="PATH_DBMDFCS" Value="PATH_TEMP_BROWSE" Order="3" />
</Control>
Do the same for your .ldf file.
K.I.S.S
I have a very easy solution. We can use the ConfigurableDirectory attribute of feature to enable the browse directory. It works well for me.
<Feature Id="OCMSnapshotConfigAppFeature" Title="OCM Snapshot Configuration" Level="1" ConfigurableDirectory="INSTALLDIR">