Populating Wix Combo Box - wix

Im using the code from from this link
and my Wix Dialogs looks like this
<Control Id="DummyComboBox" Hidden="yes" Type="ComboBox" Sorted="yes" ComboList="yes" Property="DUMMYPROPERTY" X="65" Y="60" Width="150" Height="18">
<ComboBox Property="DUMMYPROPERTY">
<ListItem Text="Dummy" Value="Dummy"/>
</ComboBox>
</Control>
<Control Id="SQLServer" Type="ComboBox" Sorted="yes" ComboList="yes" X="150" Y="100" Width="110" Height="18" Property="DBSERVER"/>
<Control Id="SQLServerLabel" Type="Text" X="25" Y="100" Width="90" Height="18" NoPrefix="yes" Text="!(loc.SQLServerLabel)"/>
<Control Id="SQLDatabaseName" Type="Edit" X="150" Y="120" Width="110" Height="18" Property="SQLDBNAME"/>
<Control Id="SQLDBServerLabel" Type="Text" X="25" Y="120" Width="90" Height="18" NoPrefix="yes" Text="!(loc.SQLDatabaseLabel)"/>
<Control Id="SQLUser" Type="Edit" X="150" Y="140" Width="110" Height="18" Property="SQLUSER"/>
<Control Id="SQLUServerLabel" Type="Text" X="25" Y="140" Width="90" Height="18" NoPrefix="yes" Text="!(loc.SQLUserLabel)"/>
<Control Id="SQLPassword" Type="Edit" X="150" Y="160" Width="110" Height="18" Property="SQLPASSWORD" Password="yes"/>
<Control Id="SQLPServerLabel" Type="Text" X="25" Y="160" Width="90" Height="18" NoPrefix="yes" Text="!(loc.SQLPasswordLabel)"/>
I have walked through the code and it's functioning properly. However when I display the Wix Dialog the combo box is empty. Any idea as to what I'm doing wrong

Quite simple ...
Hidden="yes"
Hidden="no"
You are hiding it.

You need to write custom actions to fill the combo boxes for e.g. for filling Server Instance combo box u may be write some thing like given below:-
public static ActionResult FillServerInstances(Session xiSession)
{
xiSession.Log("Begin CustomAction");
xiSession.Log("Opening view");
View lView = xiSession.Database.OpenView(
"DELETE FROM ComboBox WHERE ComboBox.Property='DBSRVR'");
lView.Execute();
lView = xiSession.Database.OpenView("SELECT * FROM ComboBox");
lView.Execute();
int Index = 1;
bool flag = false;
try
{
foreach (DataRow dr in Microsoft.SqlServer.Management.Smo.SmoApplication
.EnumAvailableSqlServers(false).Rows)
{
String InstanceName = dr["Name"].ToString();
if (InstanceName.Equals(xiSession["ComputerName"]
+ #"\"
+ xiSession["SQLINSTANCENAME"],
StringComparison.InvariantCultureIgnoreCase))
{ flag = true; }
Record lRecord = xiSession.Database.CreateRecord(4);
xiSession.Log("Setting record details");
lRecord.SetString(1, "DBSRVR");
lRecord.SetInteger(2, Index);
lRecord.SetString(3, InstanceName);
lRecord.SetString(4, InstanceName);
xiSession.Log("Adding record");
lView.Modify(ViewModifyMode.InsertTemporary, lRecord);
++Index;
}
}
catch (Exception ex)
{
logException(xiSession, ex);
}
if (flag)
{
xiSession["DBSRVR"] = xiSession["ComputerName"].ToString()
+ #"\" + xiSession["SQLINSTANCENAME"].ToString();
}
lView.Close();
xiSession.Log("Closing view");
lView.Close();
return ActionResult.Success;
}

Related

I need a help. Kindly find the below code

I have created two dialogs. Once clicked CustomCheckA (Nextbutton) it should go to CustomCheckB dialog and once clicked yes on the CustomCheckB dialog it should move to next new dialog. and it should hide the previous dialog. What need to be added in the below code to hide the CustomCheckA dialog
<Dialog Id='CustomCheckA' X='50' Y='50' Width='373' Height='287' Title='[ProductName]'>
<Control Id='Next' Type='PushButton' X='300' Y='261' Width='66' Height='18' Text='{\VSI_MS_Sans_Serif13.0_0_0}&Next >' TabSkip='no' Default='yes' >
<Publish Event='SpawnDialog' Value='CustomCheckB' />
<Dialog>
<Dialog Id='CustomCheckB' X='50' Y='50' Width='373' Height='100' Title='[ProductName]'>
<Control Id='NoButton' Type='PushButton' X='300' Y='60' Width='65' Height='21' Text='{\VSI_MS_Sans_Serif13.0_0_0}&No' TabSkip='no' Default='yes' Cancel='yes'>
<Publish Event='EndDialog' Value='Exit' />
</Control>
<Control Id='YesButton' Type='PushButton' X='230' Y='60' Width='65' Height='21' Text='{\VSI_MS_Sans_Serif13.0_0_0}&Yes' TabSkip='no' Default='yes' >
<Publish Event='NewDialog' Value='[CustomCheckB_NextArgs]'><![CDATA[CustomCheckB_NextArgs<>""]]></Publish>
</Control>
<Control Id='BodyText' Type='Text' X='6' Y='9' Width='345' Height='36' Text='{\VSI_MS_Sans_Serif13.0_0_0}WARNING' TabSkip='yes' NoPrefix='yes' />
</Dialog>

Variable value isn't changing according to checkbox value from rtf theme

Preparing a bootstrap application to install some msi packages. Have option to choose the packages to install. But the variable value is not changing as per the user selection.
This is how I use variable in my Bundle.wxs file
<Variable Name="spectrumDb" Persisted="yes" bal:Overridable="yes" Value="1" />
<Variable Name="spectrumGateway" Persisted="yes" bal:Overridable="yes" Value="1" />
<Variable Name="spectrumServiceManager" Persisted="yes" bal:Overridable="yes" Value="1" />
<Variable Name="spectrumIISparts" Persisted="yes" bal:Overridable="yes" Value="1" />
<Variable Name="spectrumConnecter" Persisted="yes" bal:Overridable="yes" Value="1" />
I have some checkboxes in rtf theme for the user to select components to install
<Page Name="Options">
<Text X="11" Y="65" Width="-11" Height="30" FontId="2" DisablePrefix="yes">Select components</Text>
<Checkbox Name="spectrumDb" X="40" Y="120" Width="200" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="no" >spectrumDb</Checkbox>
<Checkbox Name="spectrumGateway" X="40" Y="140" Width="200" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="no">spectrumGateway</Checkbox>
<Checkbox Name="spectrumServiceManager" X="40" Y="160" Width="200" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="no" >spectrumServiceManager</Checkbox>
<Checkbox Name="spectrumIISparts" X="40" Y="180" Width="200" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="no" >spectrumIISparts</Checkbox>
<Checkbox Name="spectrumConnecter" X="40" Y="200" Width="200" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="no" >spectrumConnecter</Checkbox>
</Page>
The installer install irrespective of the checkbox value. This is the part of logfile where I find that
[0404:0B44][2018-05-28T08:43:07]i000: Running detect complete custom action
[0404:0B44][2018-05-28T08:43:07]i199: Detect complete, result: 0x0
[0404:178C][2018-05-28T08:43:09]i000: Setting numeric variable 'EulaAcceptCheckbox' to value 1
[0404:178C][2018-05-28T08:43:20]i000: Setting numeric variable 'spectrumDb' to value 1
[0404:178C][2018-05-28T08:43:20]i000: Setting numeric variable 'spectrumGateway' to value 1
[0404:178C][2018-05-28T08:43:20]i000: Setting numeric variable 'spectrumServiceManager' to value 1
[0404:178C][2018-05-28T08:43:20]i000: Setting numeric variable 'spectrumIISparts' to value 1
[0404:178C][2018-05-28T08:43:20]i000: Setting numeric variable 'spectrumConnecter' to value 1
I use wix 3.11 to make this project.
ide is visual studio 2010.
bootstrap application type ref WixExtendedBootstrapperApplication.RtfLicense
The bootstrapper will set the variable when it runs this function:
void SavePageSettings(
__in WIXSTDBA_PAGE page
)
{
THEME_PAGE* pPage = NULL;
pPage = ThemeGetPage(m_pTheme, m_rgdwPageIds[page]);
if (pPage)
{
for (DWORD i = 0; i < pPage->cControlIndices; ++i)
{
// Loop through all the checkbox controls (or buttons with BS_AUTORADIOBUTTON) with names and set a Burn variable with that name to true or false.
THEME_CONTROL* pControl = m_pTheme->rgControls + pPage->rgdwControlIndices[i];
if ((THEME_CONTROL_TYPE_CHECKBOX == pControl->type) ||
(THEME_CONTROL_TYPE_BUTTON == pControl->type && (BS_AUTORADIOBUTTON == (BS_AUTORADIOBUTTON & pControl->dwStyle)) &&
pControl->sczName && *pControl->sczName))
{
BOOL bChecked = ThemeIsControlChecked(m_pTheme, pControl->wId);
m_pEngine->SetVariableNumeric(pControl->sczName, bChecked ? 1 : 0);
}
// Loop through all the editbox controls with names and set a Burn variable with that name to the contents.
if (THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName && WIXSTDBA_CONTROL_FOLDER_EDITBOX != pControl->wId)
{
LPWSTR sczValue = NULL;
ThemeGetTextControl(m_pTheme, pControl->wId, &sczValue);
m_pEngine->SetVariableString(pControl->sczName, sczValue);
}
}
}
}
The SetVariableNumeric function won't log anything for an already existing variable.
You can verify your variables are being set by running your bootstrapper, unchecking a few check boxes, going to the next page, and then cancelling your bootstrapper.
When you close the bootstrapper it logs all variables and their values. In the logs after you close the bootstrapper, you should see that the variables corresponding to the checkboxes you unchecked should now have a value of 0.

Changing the foreground colour of a button

I have a list of contacts, I want to display the alphabet and grey out the letters that do not have corresponding contacts.
in my Model I have:
public class ContactInitial
{
public string Initial { get; set; }
}
This is derived from the database.
In my View I have the following
<StackPanel Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" Width="17">
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">A</Button >
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">B</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">C</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">D</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">E</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">F</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">G</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">H</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">I</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">J</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">K</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">L</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">M</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">N</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">O</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">P</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">Q</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">R</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">S</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">T</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">U</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">V</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">W</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">X</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">Y</Button>
<Button Height="17" Background="#FFFBF5A6" BorderBrush="{x:Null}">Z</Button>
</StackPanel>
I am struggling to work out how I bind the foreground colour to be grey if the letter is not in the ContactInitial and black if it is.
Thanks for your help
I would implement it with a style, which you could put to the resources of your window, or your container control, for the style would be applied to all buttons in window/control.
In this style you can put a trigger, which will triggered, if the condition is true. The condition I would check in a multi value converter, which should be used in the binding of you view model property and Content property of the button.
This one should work:
<Window.DataContext>
<local:ViewModel ></local:ViewModel>
</Window.DataContext>
<Window.Resources>
<local:ContainsStringConverter x:Key="strContConv"/>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Gray"/>
<Style.Triggers>
<DataTrigger Value="true">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource strContConv}">
<Binding Path="InitialString"/>
<Binding RelativeSource="{RelativeSource Self}" Path="Content"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
using System;
using System.Globalization;
using System.Linq;
using System.Windows.Data;
public class ContainsStringConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values==null || values.Length<2 || !values.All(v=>v is string))
{
return false;
}
var retVal = true;
var initalStr = values[0] as string;
for (int i = 1; i < values.Length; i++)
{
retVal &= initalStr.Contains(values[i] as string);
}
return retVal;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class ViewModel : ViewModelBase
{
public ViewModel()
{
_initialString = Model.Initial;
}
public ContactInitial Model { get; set; } = new ContactInitial { Initial = "AC" };
public string InitialString
{
get
{
return _initialString;
}
set
{
if (value != _initialString)
{
_initialString = value;
Model.Initial = _initialString;
NotifyPropertyChanged(nameof(InitialString));
}
}
}
private string _initialString;
}

Using checkboxes wix

Hi I was trying to launch a custom action from a radio button but realized this cannot be done. Instead I created two checkboxes. I want them to have a shared property which I have done so as shown in my code but I would need for the user only to be able to select one at a time not both.
Heres my code:
<Control Id="CheckBoxLock" Type="CheckBox" Text="DiskID/NIC Adapter Address" Property="LOCKTYPE" X="50" Y="215" Width="200" Height="15" CheckBoxValue="0">
</Control>
<Control Id="CheckBoxLock2" Type="CheckBox" Text="Hardware Key Serial Number" CheckBoxPropertyRef="LOCKTYPE" X="50" Y="230" Width="200" Height="15" CheckBoxValue="1">
<Publish Event="DoAction" Value="OnLockOptionModified"><![CDATA[LOCKTYPE = "1"]]></Publish>
</Control>
Any help would be greatly appreciated. Thanks
Long way around it but I created a work around that works:
<Control Id="CheckBoxLock" Type="CheckBox" Text="DiskID/NIC Adapter Address" Property="LOCKTYPESW" X="90" Y="215" Width="200" Height="15" CheckBoxValue="0">
<Publish Property="LOCKTYPE" Value="[LOCKTYPESW]">1</Publish>
<Publish Property="LOCKTYPEHW" Value="{}">1</Publish>
<Publish Event="DoAction" Value="OnLockOptionModified"><![CDATA[LOCKTYPE = "0"]]></Publish>
</Control>
<Control Id="CheckBoxLock2" Type="CheckBox" Text="Hardware Key Serial Number" Property="LOCKTYPEHW" X="90" Y="230" Width="200" Height="15" CheckBoxValue="1">
<Publish Property="LOCKTYPE" Value="[LOCKTYPEHW]">1</Publish>
<Publish Property="LOCKTYPESW" Value="{}">1</Publish>
<Publish Event="DoAction" Value="OnLockOptionModified"><![CDATA[LOCKTYPE = "1"]]></Publish>
</Control>
Then my custom action reads the LOCKTYPE property. Hope this helps someone else as it has taken me two hours figuring it out..:)

How to get a context menu for edit boxes within WIX 3.6?

I was looking through a bug reported with some of my work's installer code yesterday and found that right click doesn't open a context menu for any of our installers.
The context menu is displayed for password boxes, so paste of me thinks it's a setting I missed when ploughing through the documentation, but I've not seen anything on google.
Is it a bug? Missing setting or a design feature?
Code is very simple and like this:
(Working Case: Password Box)
<Control Id="Label2" Type="Text" X="15" Y="123" Width="85" Height="18" Transparent="yes" Text="Password:" />
<Control Id="Edit2" Type="Text" Password="yes" X="100" Y="120" Width="235" Height="18" Property="PASSWORD" Text="[PASSWORD]" ToolTip="The password for the activation service to register the application." />
(Failing Case: Edit or Text Box)
<Control Id="Label1" Type="Text" X="15" Y="103" Width="80" Height="18" Transparent="yes" Text="Username:" />
<Control Id="Edit1" Type="Edit" X="100" Y="100" Width="235" Height="18" Property="ACTIVATIONUSERNAME" Text="[ACTIVATIONUSERNAME]" ToolTip="The username for the activation service to register the application." />
Cheers,
J
P.S I checked WIX 3.5 and the same issue seems to occur.
I've seen many times that MSI wizard does not have context menu in edit boxes. I guess it's the bug (or the feature) of Windows Installer. It subclasses all standard controls, i.e. changes their WndProc to new one, and in this case it may block context menu from appearing, perhaps unintentionally.