I am trying to populate values using custom actions and want to bind the values into combobox which is inside product.wxs.
Can anyone guide me how to bind values if I want to populate a list of countries inside the combobox?
I am struggling with how to pass this value so the values will show inside combox while executing my MSI setup.
Below provide the code which I am trying:
public static ActionResult FillList(Session xiSession)
{
Dictionary<string, string> _co = new Dictionary<string, string>();
_co.Add(String.Empty, String.Empty);
_co.Add("US", "United States");
_co.Add("CA", "Canada");
_co.Add("MX", "Mexico");
xiSession.Log("Return success");
return ActionResult.Success;
}
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProjectComboTest" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<UI>
<UIRef Id="WixUI_Mondo" />
<Dialog Id="MyCustomDlg" Width="500" Height="260">
<Control Id="ComboBoxMain" Type="ComboBox" X="10" Y="60" Width="300" Height="17" Property="COUNTRIES" />
<Control Id="ButtonMain" Type="PushButton" X="320" Y="60" Width="40" Height="17" Text="Show">
<Publish Property="COMBOVALUEFORMATTED" Order="1" Value="[COUNTRIES]" />
</Control>
<Control Id="LabelMain" Type="Text" X="10" Y="80" Width="360" Height="17" Property="COMBOVALUEFORMATTED" Text="[COMBOVALUEFORMATTED]" />
</Dialog>
</UI>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProjectComboTest" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
</ComponentGroup>
</Fragment>
You need to insert row into ComboBox table to bind the List values. If you open the msi in ORCA Editor, you can find the msi tables and rows.
You should include EnsureTable element if you don’t use any other ComboBox element in your msi.
<EnsureTable Id="ComboBox"/>
You can insert the rows from Custom action.
static int index = 1;
public static void FillComboBox(Session session, string text, string value)
{
View view = session.Database.OpenView("SELECT * FROM ComboBox");
view.Execute();
Record record = session.Database.CreateRecord(4);
record.SetString(1, "COUNTRIES");
record.SetInteger(2, index);
record.SetString(3, value);
record.SetString(4, text);
view.Modify(ViewModifyMode.InsertTemporary, record);
view.Close();
index++;
}
Inside the Custom action call the FillComboBox method.
public static ActionResult FillList(Session xiSession)
{
FillComboBox(xiSession, "US", "United States");
FillComboBox(xiSession, "CA", "Canada");
FillComboBox(xiSession, "MX", "Mexico");
return ActionResult.Success;
}
Execute the Custom action in InstallUIsequence before run that Combo Box dialog.
<InstallUISequence>
<Custom Action="INSERT_ROWS" After="AppSearch">Not Installed</Custom>
</InstallUISequence>
Related
I am creating a new WIX installer. The installation is based on the customer's existing database. At the very first installation I have the information of the already installed features only in the database. So I have to query theese features from it and the installer shouldn't execute its activation scripts. Every feature has a property and from a custom action I set theese properties but the conditional SQL script execution is not working. I've created a sample wxs source file. Could you help me what is wrong with it?
<?xml version='1.0' encoding='UTF-8'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:util='http://schemas.microsoft.com/wix/UtilExtension' xmlns:sql='http://schemas.microsoft.com/wix/SqlExtension'>
<!-- https://wixtoolset.org/documentation/manual/v3/xsd/wix/product.html -->
<Product Id='BC075295-7BB8-4B82-89AC-3F81681130CC' Name='XXX' UpgradeCode='4AD0BCB8-B1BB-4FE1-ABEE-58E93321AAC5' Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='XXX'>
<Package Id='*' Keywords='Installer' Description="XXX Installer" InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252'/>
<Media Id='1' Cabinet='Andoc.cab' EmbedCab='yes' />
<Binary Id="WixCustomActions" SourceFile="CustomAction.CA.dll" />
<Binary Id="sqlScriptBinaryKey" SourceFile="insert.sql" />
<CustomAction Id="SetExecuteScriptCondition" BinaryKey="WixCustomActions" DllEntry="SetExecuteScriptCondition" Execute="immediate" Return="check" />
<Property Id="EXECUTE_SCRIPT" Value="NO" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="XXX" />
</Directory>
<Component Id="componentSqlScript" Directory="INSTALLDIR" Guid="1af938ef-6788-a0e1-2370-a6c2620c9dCC">
<Condition>EXECUTE_SCRIPT = "YES"</Condition>
<sql:SqlDatabase Id="db" Database="[DATABASE_NAME]" Server="[DATABASE_SERVER]" CreateOnInstall="yes" DropOnUninstall="no" ContinueOnError="no">
<sql:SqlScript Id="SqlScriptId" BinaryKey="sqlScriptBinaryKey" ExecuteOnInstall="yes" ExecuteOnUninstall="no" ContinueOnError="no" />
</sql:SqlDatabase>
<CreateFolder />
</Component>
<Feature Id="feature" Title="xxx" Description="xxx" ConfigurableDirectory="INSTALLDIR" Level="1">
<ComponentRef Id="componentSqlScript" />
</Feature>
<InstallExecuteSequence>
<Custom Action='SetExecuteScriptCondition' Before='InstallInitialize' />
</InstallExecuteSequence>
<UI>
<UIRef Id="WixUI_Mondo" />
</UI>
</Product>
</Wix>
My custom action looks like this.
[CustomAction]
public static ActionResult SetExecuteScriptCondition(Session session)
{
session["EXECUTE_SCRIPT"] = "YES";
return ActionResult.Success;
}
In the log I see that the EXECUTE_SCRIPT property value is 'YES' but the insert.sql script is not executed.
I've found a workaround to solve this problem by creating a subfeature to the sql component and moving the component condition to the feature level. And instead of InstallExecuteSequence I execute my custom action in InstallUISequence.
<Feature Id="feature" Title="xxx" Description="xxx" ConfigurableDirectory="INSTALLDIR" Level="1">
<Feature Id="feature_script" Title="script" Description="script" Display="hidden" Level="1" >
<Condition Level="0">EXECUTE_SCRIPT = "NO"</Condition>
<Condition Level="1">EXECUTE_SCRIPT = "YES"</Condition>
<ComponentRef Id="componentSqlScript" />
</Feature>
</Feature>
<InstallUISequence>
<Custom Action='SetExecuteScriptCondition' Before='LaunchConditions' />
</InstallUISequence>
InstallInitialize is too late, as the condition for your component 'componentSqlScript' is evaluated during costing. That's the reason setting that property didn't appear to work.
You need to schedule your action before 'CostInitialize', sequence it in both UI and Execute sequences (since the UI sequence doesn't necessarily run, and if costing is also preformed in the UI sequence then the execute sequence will be too late). You should add Execute="firstSequence" to your CustomAction element, and you should add Secure="yes" to your Property element, to prevent running code excessively and prevent issues where public property values aren't always set to the execute sequence.
I am trying to create a dual purpose MSI file using WiX. I have followed the instructions for WixUI_Advanced as well as the instructions for Single Package Authoring. This seems to work fine when I default to having a per user install by default (MSIINSTALLPERUSER = 1) and allow the user to select a per machine install. However setting it to install per machine by default (MSIINSTALLPERUSER empty) always results in a UAC prompt even when the user selects a per user install. The per user install is only writing a single file to a non admin directory and definitely does not require elevated privileges.
I have also tried following this guide which everyone seems to be using to do Single Package Authoring with WiX but the results are exactly the same. A UAC prompt appears if per machine is the default and per user is selected but not if per user is the default and per user is selected.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="DE75C3B3-6398-4F25-9048-FB7EEE5F6EBF" Name="MyApp" Language="1033" Version="1.0.0" Manufacturer="Company" UpgradeCode="ED573078-CC3E-4299-9E04-043B1EDC08DB">
<Package InstallerVersion="500" Compressed="yes" />
<!--Single Package Authoring-->
<Property Id="MSIINSTALLPERUSER" Secure="yes" Value="{}"/>
<Property Id="ALLUSERS" Secure="yes" Value="2"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" CabinetTemplate="arc{0}" CompressionLevel="high"/>
<Feature Id="ProductFeature" Title="MyApp" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<UI>
<UIRef Id="WixUI_Advanced" />
</UI>
<Property Id="ApplicationFolderName" Value="MyApp" />
<Property Id="WixAppFolder" Value="WixPerMachineFolder" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder" Name="PFiles">
<Directory Id="APPLICATIONFOLDER" Name="MyApp">
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="APPLICATIONFOLDER">
<Component Id="MyApp.exe" Guid="903EDAFD-F513-407D-85A0-D737013B9B57">
<File Id="MyApp.exe" Source="MyApp.exe" KeyPath="yes" Checksum="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Looking through the install log I see the following entries:
Product not registered: beginning first-time install
PROPERTY CHANGE: Modifying ALLUSERS property. Its current value is '2'. Its new value: '1'.
PROPERTY CHANGE: Deleting MSIINSTALLPERUSER property. Its current value is '{}'.
...
Action: InstallScopeDlg. Dialog created
PROPERTY CHANGE: Modifying WixAppFolder property. Its current value is 'WixPerMachineFolder'. Its new value: 'WixPerUserFolder'.
PROPERTY CHANGE: Deleting ALLUSERS property. Its current value is '1'.
...
Product not registered: beginning first-time install
PROPERTY CHANGE: Deleting ALLUSERS property. Its current value is '2'.
PROPERTY CHANGE: Deleting MSIINSTALLPERUSER property. Its current value is '{}'.
Based on the install log I tried reintroducing the lines replaced in the modified WixUI file from this guide which update the ALLUSERS property as it seems as though this was being set to a value of 1 for the per user install which would explain the UAC prompt. Having both the following lines from the Russian blog and the original WixUI_Advanced does seem to work.
<Publish Dialog="InstallScopeDlg" Control="Next" Property="ALLUSERS" Value="{}" Order="2">
WixAppFolder = "WixPerUserFolder"
</Publish>
<Publish Dialog="InstallScopeDlg" Control="Next" Property="ALLUSERS" Value="1" Order="3">
WixAppFolder = "WixPerMachineFolder"
</Publish>
<Publish Dialog="InstallScopeDlg" Control="Next" Property="MSIINSTALLPERUSER" Value="1" Order="3">
WixAppFolder = "WixPerUserFolder"
</Publish>
<Publish Dialog="InstallScopeDlg" Control="Next" Property="MSIINSTALLPERUSER" Value="{}" Order="2">
WixAppFolder = "WixPerMachineFolder"
</Publish>
It seems as though both ALLUSERS and MSIINSTALLPERUSER needs to be set based on the user's choice to allow installation with no Administrator privileges when a per machine install is the default. I can't find anywhere else online to confirm my findings however.
There are three properties to control the default install scope when using WixUI_Advanced UI: 'ALLUSERS', 'Privileged' and 'MSIINSTALLPERUSER'.
The property 'WixAppFolder' will control which radio button is selected by default when 'advanced' button is clicked.
And there is a konwn bug of wix needs a workaround: https://github.com/wixtoolset/issues/issues/2376
In summary, the wix config can be:
Per user
<Property Id='WixAppFolder' Value='WixPerUserFolder' />
<Property Id='ALLUSERS' Value='2' />
<Property Id='Privileged' Value='0' />
<Property Id='MSIINSTALLPERUSER' Value='1' />
<UI>
<UIRef Id='WixUI_Advanced' />
<UIRef Id='WixUI_ErrorProgressText' />
<Publish Dialog='InstallScopeDlg' Control='Next' Property='MSIINSTALLPERUSER' Value='1' Order='3'>WixAppFolder = "WixPerUserFolder"
<Publish Dialog='InstallScopeDlg' Control='Next' Property='MSIINSTALLPERUSER' Value='{}' Order='2'>WixAppFolder = "WixPerMachineFolder"
<Publish Dialog='InstallScopeDlg' Control='Next' Event='DoAction' Value='WixSetDefaultPerMachineFolder' Order='3'>WixAppFolder = "WixPerMachineFolder"
<Publish Dialog='InstallScopeDlg' Control='Next' Event='DoAction' Value='WixSetDefaultPerUserFolder' Order='3'>WixAppFolder = "WixPerUserFolder"
</UI>
Per machine
<Property Id='WixAppFolder' Value='WixPerMachineFolder' />
<Property Id='ALLUSERS' Value='1' />
<Property Id='Privileged' Value='1' />
<Property Id='MSIINSTALLPERUSER' Value='0' />
<UI>
<UIRef Id='WixUI_Advanced' />
<UIRef Id='WixUI_ErrorProgressText' />
<Publish Dialog='InstallScopeDlg' Control='Next' Property='MSIINSTALLPERUSER' Value='1' Order='3'>WixAppFolder = "WixPerUserFolder"
<Publish Dialog='InstallScopeDlg' Control='Next' Property='MSIINSTALLPERUSER' Value='{}' Order='2'>WixAppFolder = "WixPerMachineFolder"
<Publish Dialog='InstallScopeDlg' Control='Next' Event='DoAction' Value='WixSetDefaultPerMachineFolder' Order='3'>WixAppFolder = "WixPerMachineFolder"
<Publish Dialog='InstallScopeDlg' Control='Next' Event='DoAction' Value='WixSetDefaultPerUserFolder' Order='3'>WixAppFolder = "WixPerUserFolder"
</UI>
BTW, I created a project to simplify the configuration of wix. Hope it can help: https://github.com/xinnj/WiXCover
im trying to create a custom installer Setup, using wix-template.
Everything works fine, except the use of the 'edit' control in a custom dialog.
Heres the code of the Dialog file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI Id="InstallDlg_UI" >
<TextStyle Id="Tahoma_Regular" FaceName="Tahoma" Size="8" />
<Property Id="DefaultUIFont" Value="Tahoma_Regular" />
<Property Id="TEST" Value="test" Secure="yes"/>
<Dialog Id="InstallDlg" Width="320" Height="180" NoMinimize="yes" Title="RC Proxy Service" >
<Control Id="CRMServerTxt" Type="Text" Width="80" Height="17" X="5" Y="5" Text="CRM-Server:"/>
<Control Id="CRM" Type="Edit" Width="100" Height="17" X ="90" Y="5" Indirect="yes" Property="TEST"/>
<Control Id="SQLServerTxt" Type="Text" Width="80" Height="17" X="5" Y="25" Text="SQL-Server:" />
<Control Id="Install" Type="PushButton" X="150" Y="155" Width="80" Height="17" Text="Install" />
<Control Id="Cancel" Type="PushButton" X="235" Y="155" Width="80" Height="17" Text="Cancel"/>
</Dialog>
<InstallUISequence>
<Show Dialog="InstallDlg" Before="ExecuteAction"/>
</InstallUISequence>
</UI>
And this is the product.wxs file that references the dialog.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="TestInstaller" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="b5c70750-4fdb-4ff1-8e0f-0bb8bcd47d9e">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of TestInstaller is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="TestSetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<UIRef Id="InstallDlg_UI"/>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="TestSetup" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component>
<File Source="$(var.SetupSample.TargetPath)" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Im always getting error code 2228 when i try to execute the msi file. Without the 'edit' control everything works.
Im using Visual Studio 2013 and the Wix-Toolset v3.9 R2.
Someone any ideas?
Thanks Andree
It seem to me that the problem is resolved.
I have missed to add the basic dialogs that are needed for the setup.
After adding the progress and the finished dialog all works fine.
This my Product.wxs:
In the custom action, I want to make changes in the httpd.conf file before Apache 2.4 service is installed, actually the Apache 2.4 Service takes Configuration parameters from httpd.conf, so its mandatory for the code that the changes should be made before installation of service, If any idea help me on this ?
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'>
<Product Id="*" Name="MyExampleProject" Language="1033" Version="1.0.0.0" Manufacturer="Mq" UpgradeCode="08bd3c48-deef-4370-ab94-f8b4d49406e3">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<!--System Configuration Condition - Installation install only above Windows XP-->
<Condition Message="This application is only supported on Windows XP, or higher.">
<![CDATA[Installed OR (VersionNT >= 501)]]>
</Condition>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='INSTALLDIR' Name='AgentFramework'>
<Directory Id='INSTALLBIN' Name='bin'/>
<Directory Id='INSTALLCONF' Name='conf'/>
<Directory Id='INSTALLMODULES' Name='modules'/>
</Directory>
</Directory>
</Directory>
<Feature
Id = "ProductFeature1"
Title = "AgentFramework"
Level = "1"
Absent="allow">
<ComponentRef Id='libapr_dll'/>
<ComponentRef Id='libapriconv_dll'/>
<ComponentRef Id='libaprutil_dll'/>
<ComponentRef Id='libhttpd_dll'/>
<ComponentRef Id='Pcre_dll'/>
<ComponentRef Id='Configurationfile'/>
<ComponentRef Id='Authzmodule'/>
<ComponentRef Id='Dirmodule'/>
<ComponentRef Id='ServiceComponent'/>
</Feature>
<DirectoryRef Id='INSTALLCONF'>
<Component Id='Configurationfile' Guid='2E0D2957-10EB-463A-A4FC-62B9062FE8A3'>
<File Id='Configurationfile' Name='httpd.conf' DiskId='1' Source='$(sys.CURRENTDIR)\httpd.conf' KeyPath='yes'>
</File>
</Component>
</DirectoryRef>
<DirectoryRef Id='INSTALLMODULES'>
<Component Id='Authzmodule' Guid='62AA97B6-7821-4CB4-9F89-B2A8FF0CC6BD'>
<File Id='Authzmodule' Name='mod_authz_core.so' DiskId='1' Source='$(sys.CURRENTDIR)\mod_authz_core.so' KeyPath='yes'>
</File>
</Component>
<Component Id='Dirmodule' Guid='9966BB3B-8296-43B9-A6DC-712561303329'>
<File Id='Dirmodule' Name='mod_dir.so' DiskId='1' Source='$(sys.CURRENTDIR)\mod_dir.so' KeyPath='yes'>
</File>
</Component>
</DirectoryRef>
<DirectoryRef Id='INSTALLBIN'>
<Component Id='libapr_dll' Guid='FB82D093-0B32-465B-8D8B-08B3127EB414'>
<File Id='libapr_dll' Name='libapr-1.dll' DiskId='1' Source='$(sys.CURRENTDIR)\libapr-1.dll' KeyPath='yes'>
</File>
</Component>
<Component Id='libapriconv_dll' Guid='667D6D5B-6FE4-4A6B-827F-C496239628E2'>
<File Id='libapriconv_dll' Name='libapriconv-1.dll' DiskId='1' Source='$(sys.CURRENTDIR)\libapriconv-1.dll' KeyPath='yes'>
</File>
</Component>
<Component Id='libaprutil_dll' Guid='72C688D2-8E25-49D9-9E76-F6BDBC33D394'>
<File Id='libaprutil_dll' Name='libaprutil-1.dll' DiskId='1' Source='$(sys.CURRENTDIR)\libaprutil-1.dll' KeyPath='yes'>
</File>
</Component>
<Component Id='libhttpd_dll' Guid='8946D5B1-0EA2-443E-8C20-CD8D877ACF75'>
<File Id='libhttpd_dll' Name='libhttpd.dll' DiskId='1' Source='$(sys.CURRENTDIR)\libhttpd.dll' KeyPath='yes'>
</File>
</Component>
<Component Id='Pcre_dll' Guid='0466BB2A-137C-4A95-A510-43E7A274F834'>
<File Id='Pcre_dll' Name='pcre.dll' DiskId='1' Source='$(sys.CURRENTDIR)\pcre.dll' KeyPath='yes'>
</File>
</Component>
<Component Id ="ServiceComponent" Guid="8A1BF3F0-8A84-456E-816A-5907B40B2DDB" >
<File Id='Applicationfile' Name='httpd.exe' DiskId='1' Source='$(sys.CURRENTDIR)\httpd.exe' KeyPath='yes'>
</File>
<ServiceInstall Id="ServiceComponent" Type="ownProcess" Name="Apache2.4"
DisplayName="Apache2.4" Description="Service"
Arguments="-k runservice" Start="auto" Account="LocalSystem" ErrorControl="normal"
Vital="yes" >
<util:PermissionEx User="Everyone" ServicePauseContinue="yes" ServiceQueryStatus="yes"
ServiceStart="yes" ServiceStop="yes" ServiceUserDefinedControl="yes" /> </ServiceInstall>
<ServiceControl Id="ServiceComponent" Start="install" Stop="both"
Remove="uninstall" Name="Apache2.4" Wait="yes" />
</Component>
</DirectoryRef>
<UIRef Id="CustomizeDlg" />
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
<DialogRef Id="UserRegistrationDlg" />
<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>
<Property Id="PIDTemplate"><![CDATA[1234<####-####-####-####>####]]></Property>
<CustomAction Id='CheckLogLevel' BinaryKey='CheckLogLevel' DllEntry='CustomAction1' />
<Binary Id ='CheckLogLevel' SourceFile='$(sys.CURRENTDIR)\MqAgent_LogLevel.dll'/>
<WixVariable Id="WixUIBannerBmp" Value="C:\Image\style39_banner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="C:\Image\style39_dialog.bmp" />
</Product>
</Wix>
Here's CustomizeDlg.wxs :
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI Id ="CustomizeDlg">
<ComboBox Property="SETUPLOGLEVEL">
<ListItem Text="Debug" Value="1" />
<ListItem Text="info" Value="2" />
<ListItem Text="warn" Value="3" />
</ComboBox>
<Dialog Id="UserRegistrationDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="NameEdit" Type="ComboBox" X="52" Y="48" Width="156" Height="10" ComboList="yes"
Property="SETUPLOGLEVEL" Sorted="no" RightToLeft="yes"/>
<Control Id="CDKeyLabel" Type="Text" X="45" Y="147" Width="50" Height="10" TabSkip="no">
<Text>CD &Key:</Text>
</Control>
<Control Id="CDKeyEdit" Type="MaskedEdit" X="45" Y="159" Width="250" Height="16" Property="PIDKEY" Text="[PIDTemplate]" />
<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="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
<Text>Please mention the log level</Text>
</Control>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
<Text>{\WixUI_Font_Title}Select Log Level</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
</Dialog>
</UI>
</Fragment>
</Wix>
What I've done before was put all my custom action's logic in an executable and then call the executable, which worked nicely. It turns out that WiX provides various Custom Action Projects within Visual Studio that remove the need to create a stand alone executable, see here for a nice example by James Schaffer.
As for controlling when the custom action is executed, you control this by adding an entry in the InstallExecuteSequence node of the *.wxs file, like this...
<InstallExecuteSequence>
<Custom Action="CheckLogLevel" Before="InstallServices" />
</InstallExecuteSequence>
... where CheckLogLevel is my custom action, and it's being directed to be run before the InstallServices action.
mattyB gets a big thumbs up.
To better understand this problem though I think it's important to view the MSI in Orca. Orca is a MS product which can view the lifecycle of MSI files. It also allows you to directly edit the MSI file.
Below is a screenshot of the "jobs" which will be run by the installer in sequence order. mattyB mentioned the "InstallServices" job, which I have highlighted in the screenshot below. We need to make sure all of our custom actions occur BEFORE this job runs. From here it's as simple as setting the "Before" attribute in the "Custom" tag to a value of "InstallServices."
Hopefully this helps to further demystify WiX.
I am new to create MSI installer using wix tool,here i have a query please help me how to resolve this .
My query is : I have create a custom UI , in this i have a combo box control and i have bind the combo box values as dynamically using custom Action method it's working fine . Now, i want pass the parameters(combo box selected value) to custom action method,i don't know how to pass parameters .I goggled but i did not get answer please help me.
Here is my code
<Binary Id="CustomActions" SourceFile="D:\WIX Projects\ExampleSetup\CustomAction1\bin\Debug\CustomAction1.CA.dll" />
<CustomAction Id='Action1' BinaryKey='CustomActions' DllEntry='FillServerInstances' Execute='immediate' Return='check' />
<UI>
<Dialog Id="CustomWelcomeEulaDlg" Width="600" Height="450" Title="!(loc.WelcomeEulaDlg_Title)">
<Control Id="Bitmap" Type="Bitmap" X="0" Y="44" Width="600" Height="380" TabSkip="no" Text="MainImage" />
<Control Id="Next" Type="PushButton" X="290" Y="430" Width="60" Height="17" Default="yes" Text="Next">
<Publish Event="DoAction" Value="Action1">1</Publish>
<Publish Event="NewDialog" Value="LicenseAgreementDlgs"><![CDATA[1]]></Publish>
<Publish Event="ReinstallMode" Value="ecmus"><![CDATA[Installed = 1]]></Publish>
</Control>
<Control Id="Cancel" Type="PushButton" X="350" Y="430" Width="56" Height="17" Cancel="yes" Text="Cancel">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="Title" Type="Text" X="15" Y="6" Width="300" Height="15" Transparent="yes" NoPrefix="yes">
<Text>[DlgTitleFont]Welcome to the [ProductName] [Wizard]</Text>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="600" Height="0" />
</Dialog>
Latest Code
<Product Id="22d32870-651b-4eee-a622-27b2daaade8c" Name="Small Business" Language="1033" Version="1.0.0.0" Manufacturer="Small Business Manufacturing" UpgradeCode="01b2dc2f-61f3-4ff0-a0ba-94dd4cb0829d">
<Package InstallerVersion="200" Compressed="yes" />
<Property Id="MSIFASTINSTALL" Value="3" />
<Binary Id="BIN_CustomAction" SourceFile="D:\WIX Projects\ExampleSetup\CustomAction1\bin\Debug\CustomAction1.CA.dll"/>
<Binary Id="myAction" SourceFile="D:\WIX Projects\ExampleSetup\CustomAction1\bin\Debug\CustomAction1.CA.dll"/>
<UIRef Id="WixUI_CustomMinimal" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Property Id="FILEPATH" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="Small Business Manufacturing">
<Component Id="Component" Guid="af10d5b4-5d25-474f-8360-13b6c0cd7a53">
<File Id="Component" Source="D:\WIX Projects\Small Business Manufacturing\Small Business Manufacturing\bin\Debug\Myproject.exe" Compressed="yes" KeyPath="yes" Checksum="yes" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="Installation Target" Level="1">
<ComponentRef Id="Component" />
</Feature>
<InstallExecuteSequence>
<Custom Action="myActionId" After="InstallFinalize"></Custom>
</InstallExecuteSequence>
<CustomAction Id="SetCustomActionDataValue" Return="check" Property="myActionId" Value="AnotherValue=[Sqlinstaces]" />
<UI>
<ProgressText Action="RunEXE">Configuring Foo... (this may take a few minutes).</ProgressText>
</UI>
</Product>
As far as I am aware you can't pass parameters to custom actions. You can set a property in Wix and use WcaGetProperty to access that.
I use a listbox which is similar like so:
<!--This will be populated via the custom action-->
<Control Id="ListBoxID" Type="ListBox" Property="COMPORT" Width="80" Height="40" X="80" Y="165" Indirect="no">
<ListBox Property="COMPORT">
</ListBox>
</Control>
And in my C++ Custom Action:
hr = WcaGetFormattedProperty(L"COMPORT",&szComport);
ExitOnFailure(hr, "failed to get Com Port");
EDIT:
Ok so I am assuming your ComboBox is something 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">
</ComboBox>
Make sure your property is is defined like so(ensure capital letters):
<Property Id="DUMMYPROPERTY" Secure="yes"></Property>
You do not need a custom action to send the value of the property. All you have to do is use:
LPWSTR dummyText = NULL;
hr = WcaGetProperty(L"DUMMYPROPERTY", &dummyText);
ExitOnFailure(hr, "failed to get Dummy Text");
That is for a C++ Custom Action not sure what you are using but a quick google search would tell you the relevant code to use.