How do you create a waiting dialog in WIX? - wix

I'm trying to create a dialog to display whilst the installer is checking an SQL server exists. I've used the following code:
<Control Id="Next" Type="PushButton" X="244" Y="243" Width="56" Height="17" Text="!(loc.WixUINext)">
<!--Show Waiting dialog-->
<Publish Property="SQLServerChecked" Value="0">1</Publish>
<Publish Event="SpawnWaitDialog" Value="WaitCheckSQLServerDlg">
SQLServerChecked = "1"
</Publish>
<!--Checks the SQL server exists-->
<Publish Event="DoAction" Value="CheckSQLServerExists">1</Publish>
<Publish Property="SQLServerChecked" Value="1">1</Publish>
</Control>
However my WaitCheckSQLServerDlg shows, never disappears and the Action CheckSQLServerExists doesn't get run. How would I alter my code so that the WaitCheckSQLServerDlg displays whilst the CheckSQLServerExists action is running?
Thanks

Related

Wix installer refresh page after custom action

I am looking for way to refresh current page after custom action.
My code
<Control Id="Config" Type="PushButton" .../>
<Publish Event="DoAction" Value="SetConfiguration"></Publish>
</Control>
It can be after custom action, but I don't see that Session has such an opportunity, or just adding some Event to Control that will work.
Edit:
Ok I have somethink like this:
<Control Id="Config" Type="PushButton" X="120" Y="243" Width="56" Height="17" Default="yes" Text="Config" >
<Publish Event="DoAction" Value="SetConfiguration" Order="1"></Publish>
<Condition Action="disable">EndConfig = "true"</Condition>
<Condition Action="enable">EndConfig = "false"</Condition>
<Publish Event="NewDialog" Value="IISconfiguration2">EndConfig="true</Publish>
</Control>
But how to create NewDialog after return result custom acion. Because it now do it in this same time. Set order on 1 and 2 dont work.
Try this
<Control Id="Config" Type="PushButton" X="120" Y="243" Width="56" Height="17" Default="yes" Text="Config" >
<Publish Event="DoAction" Value="SetConfiguration">1</Publish>
<Condition Action="disable">EndConfig = "true"</Condition>
<Condition Action="enable">EndConfig = "false"</Condition>
<Publish Event="NewDialog" Value="IISconfiguration2">2</Publish>
</Control>
This is a known behavior in MSI native UI.
The best work around I have is to make a clone of the dialog and transition from the original to the clone dialog (or the clone to the original) so that it looks like the same dialog to the user but it's actually a different dialog and the data will be refreshed.
Example.
On SQLDlg1:
<Control Id="Test" Type="PushButton" Text="&Test" TabSkip="no" Default="yes" Height="17" Width="56" X="283" Y="195">
<Publish Event="NewDialog" Value="SQLDlg2">1</Publish>
<Publish Event="DoAction" Value="ValidateDatabase">1</Publish>
</Control>
On SQLDlg2:
<Control Id="Test" Type="PushButton" Text="&Test" TabSkip="no" Default="yes" Height="17" Width="56" X="283" Y="195">
<Publish Event="NewDialog" Value="SQLDlg1">1</Publish>
<Publish Event="DoAction" Value="ValidateDatabase">1</Publish>
</Control>
On the next dialog I also clear the property in case they click back.
<Publish Dialog="VerifyReadyDlg" Control="Back" Property="DatabaseValid" Value="{}">1</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="SQLDlg">1</Publish>

Stop setup error inside Custom Action With WIX installer

Can i able to stop the setup if any error display inside CustomAction. As i can able display error message inside custom Action and it's dispaly the error message but as soon as i click on ok button my next UI sequence form is appearing.How i will force user to finish button?
Adding my source code:
<Binary Id="BIN_CustomAction" SourceFile="CustomAction.CA.dll" />
<CustomAction Id="CA_CheckList" BinaryKey="BIN_CustomAction" DllEntry="CA_CheckList" Execute="immediate" Impersonate="yes" Return="ignore" />
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
<DialogRef Id="UserRegistrationDlg" />
<Dialog Id="UserRegistrationDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="ComboBoxMain" Type="ComboBox" X="124" Y="158" Width="241" Height="16" Property="LOCATIONNAME">
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
<Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
</Control>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&Next">
<Publish Event="SpawnDialog" Value="SetupTypeDlg">1</Publish>
</Control>
<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>
<Control Id="Next" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&NExt">
<Publish Event="DoAction" Value="RadioButtonCheck">1</Publish>
</Control>
</Dialog>-->
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="UserRegistrationDlg" Order="3">
LicenseAccepted = "1"
</Publish>
<Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="UserRegistrationDlg">1</Publish>
</UI>
<InstallUISequence>
<Custom Action="CA_CheckList" Before="AppSearch">Not Installed</Custom>
</InstallUISequence>
[CustomAction]
public static ActionResult CA_CheckList(Session session)
{
if (installer.ListStatus == false)
{
// dispaly
Record record = new Record();
record.FormatString = string.Format("Error!");
session.Message(
InstallMessage.Error | (InstallMessage)(MessageIcon.Error) |
(InstallMessage)MessageButtons.OK,record);
return ActionResult.Failure;
}
else
{
return ActionResult.Success;
}
}
Add screen shot also proving once i click on Ok button of image(1) my next dialog i.e image (2) is appearing:- instead of what i need is Finish dialog when i am getting the error.
1)
2)
Any idea??kindly help me.
This is an old post but I'd like to answer the question in case somebody else finds this. In the custom action definition, CustomAction Id="CA_CheckList" BinaryKey="BIN_CustomAction" ..., 'Return' is set to 'ignore'. It should be set to 'check'.
It's all about returning the correct "error code" from the custom action. If you want to terminate the installation, return ActionResult.Failure from your CA.
Side note: displaying UI from inside the custom action is generally a bad idea - this scenario doesn't support silent installation the way it should go.

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">

Based on CheckBox value show the WIX Dialog

I have instakllation i have to show the Dialog based on the checkbox value. I have set the checkbox property as true initially.
<Property Id="CHECKBOX_1_PROP" Value="TRUE" />
And show the dialog based on the check box values. If it is true i have to show the Newdoalog_1 if it is false i have to show the Setup dialog
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Text="[ButtonText_Next]" TabSkip="no" Default="yes">
<Publish Event="SetTargetPath" Value="APPDIR">INSTALL</Publish>
<Publish Event="NewDialog" Value="NewDialog_1">INSTALL AND CHECKBOX_1_PROP="TRUE"</Publish>
<Publish Event="NewDialog" Value="SetupTypeDlg">INSTALL</Publish>
</Control>
<Control Id="CheckBox_1" Type="CheckBox" X="25" Y="164" Width="211" Height="26" Property="CHECKBOX_1_PROP" Text="Do you want to install the Samples" CheckBoxValue="CheckBox" TabSkip="no" Hidden="yes">
<Condition Action="show">INSTALL</Condition>
</Control>
My Problem is always show the Setup Dialog that is False condition.
Pls help on this.
I'm guessing your checkbox isn't setting the string literal "TRUE", check-boxes completely delete the property when unchecked. Setting that property to any value ("0", "true", "false", "-1") would cause it to be checked. So ignore the value, just check if the property exists or not.
<Publish Dialog="MyDlg" Control="Next" Event="NewDialog" Value="CustomDlg1">PROP1</Publish>
<Publish Dialog="MyDlg" Control="Next" Event="NewDialog" Value="CustomDlg2">Not PROP1</Publish>
To get the SetupTypeDlg to only show when CHECKBOX_1_PROP <> "TRUE" the code should look something like this:
<Publish Event="NewDialog" Value="SetupTypeDlg"><![CDATA[INSTALL AND CHECKBOX_1_PROP<>"TRUE"]]></Publish>

Install Sequence

I am writing an installer which has a EULA, and then a dialog to ask whether they want to do a 'custom install', or 'default install'.
If they select custom they get a bunch of dialogs relating to SQL settings (as shown below with the next button starting the 'StartupMenu' dialog if they have selected custom install).
If they select default the installer should skip to the 'installing' stage and not ask any more questions. How do I do this?
My next button is defined like this,
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="no" Text="Next" >
<Publish Event="NewDialog" Value="StartupMenu" >CUSTOMINSTALL = 1</Publish>
<Publish Event="EndDialog" Value="Return">CUSTOMINSTALL = 0</Publish>
</Control>
When CUSTOMINSTALL = 1 it is fine, but it is the next line, what do I have to put with CUSTOMINSTALL = 0 to make it go straight to the installation stage?
an update on this one. I found that the first issue was with my InstallUISequence table, I had to make it like this,
<InstallUISequence>
<Custom Action="CreateConnectionStrings" After="ExecuteAction">NOT Installed</Custom>
<Show Dialog="CustomInstall" After="WelcomeEulaDlg" >NOT Installed</Show>
<Show Dialog="StartupMenu" After="CustomInstall" >NOT Installed and CUSTOMINSTALL = 1</Show>
<Show Dialog="iCalibraDatabaseSelection" After="StartupMenu">NOT Installed and CUSTOMINSTALL = 1</Show>
<Show Dialog="GlobalStoreDatabaseSelection" After="iCalibraDatabaseSelection">NOT Installed and CUSTOMINSTALL = 1</Show>
</InstallUISequence>
Note that on StartupMenu, iCalibraDatabaseSelection, and GlobalStoreDatabaseSelection dialogs I have added the new condition CUSTOMINSTALL = 1.
This solves my problem when I select the 'default install' option. This skips to the installation process.
The problem I have now is when I select the 'custom install' option. I go through each of the above dialogs and the GlobalStoreDatabaseSelection dialog should be the last dialog. On that dialog I have this,
<Control Id="Install" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="no" Text="Install" >
<Publish Event="EndDialog" Value="Return"></Publish>
</Control>
But this does not progress the installer to do the actual installation. It jumps back to the StartupMenu dialog.
So I guess what does Event="EndDialog" Value="Return" actually do? Where does it jump to?