Wix - install directory depending on a condition - wix

In my wix source code, I have to look for 2 entries in the registry to get an install directory :
<Property Id="INSTALLDIR_A">
<RegistrySearch Id='RegA' Type='raw'
Root='HKLM' Key='Software\Path\To\A' Name='InstallLocation' />
<Property Id="INSTALLDIR_B">
<RegistrySearch Id='RegB' Type='raw'
Root='HKLM' Key='Software\Path\To\B' Name='InstallLocation' />
My install directory must be either INSTALLDIR_A or INSTALLDIR_B. If I had to look only to 1 entry, I would have implemented it like that :
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="My path">
<!-- further code -->
</Directory>
</Directory>
But I want INSTALLDIR to be either INSTALLDIR_A or INSTALLDIR_B depending on which one is defined. How to achieve this ?

There's a custom action SetDirectory (http://wixtoolset.org/documentation/manual/v3/xsd/wix/setdirectory.html) for that. You might try something like using the first value as default and overwriting it if the other one is set:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Software\Path\To\A" />
</Directory>
</Directory>
<SetDirectory Id="INSTALLFOLDER" Value="[INSTALLDIR_B]">INSTALLDIR_B AND NOT INSTALLDIR_A</SetDirectory>
</Fragment>

Related

How to set Wix Property from UI which user can change during installation?

I have Wix Code which simply installs a txt file in the given location
The target location is enclosed in a Property THISONE
<Fragment>
<Property Id="THISONE" Value="C:\MyFolder"/>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='APPLICATIONFOLDER' ComponentGuidGenerationSeed="{75266e3e-3781-47e3-ac29-46a2d90548f9}">
<Directory Id='MyFolder' Name='MyFolder'/>
</Directory>
</Directory>
<SetDirectory Id='APPLICATIONFOLDER' Value='[THISONE]' />
</Fragment>
<Fragment>
<Component Id="Component1" Directory="MyFolder" Win64="yes">
<File Id="FirstFile.txt"/>
</Component>
</Fragment>
I want a minimal UI with maybe just a textbox where I can edit the property value so that I can change the target installation file path.
How can I achieve that ?
Thanks in Advance
The WiXUIInstallDir may be what you want, as described in the WiX documentation.
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='APPLICATIONFOLDER' ComponentGuidGenerationSeed="{75266e3e-3781-47e3-ac29-46a2d90548f9}">
<Directory Id='MyFolder' Name='MyFolder'/>
</Directory>
</Directory>
<Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONFOLDER" />
<UIRef Id="WixUI_InstallDir" />
You must set the value of the property WIXUI_INSTALLDIR to the value of the ID of the directory you want the user to be able to specify the location of, as shown above. This is then passed to the WixUI_InstallDir dialog. Note that the directory ID must all be uppercase.
If you're using Visual Studio, you'll need to add a reference to WixUIExtension to your WiX project. See here for more details.

WiX nesting child directories under installation directory

I am creating a WiX installer and allow the user to change the installation directory INSTALL_FOLDER. If the user changes the installation directory, say to D:\Here then adding a component file to AAX_BIN_FOLDER still results in the file being added to C:\Program Files\Manufacturer\Product\Test AAX Plugin\Context\x64\Test.aaxplugin rather than D:\Here\Test AAX Plugin\Context\x64\Test.aaxplugin.
What am I doing wrong in the following XML?
<Feature Id="AAX" Title="AAX" Level="1">
<ComponentGroupRef Id="group.AAX" />
</Feature>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.Program_Files)">
<Directory Id="INSTALL_FOLDER_MANUFACTURER" Name="$(var.Manufacturer)">
<Directory Id="INSTALL_FOLDER" Name="$(var.Short_Name)">
<Directory Id="INSTALL_AAX_PLUGIN_FOLDER" Name="$(var.Short_Name) AAX Plugin">
<Directory Id="INSTALL_AAX_CONTENT" Name="Content">
<Directory Id="INSTALL_AAX_BIN_FOLDER" Name="$(var.AAX_Architecure)" />
<Directory Id="INSTALL_AAX_RESOURCES_FOLDER" Name="Resources" />
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
<ComponentGroup Id="group.AAX">
<Component Id='component.AAX' Guid='$(var.Component_Aax_Guid)' Transitive="yes" Directory="AAX_BIN_FOLDER">
<File Id="file.AAX" Source='..\..\build_release$(var.Architecture_Number)\Test.aaxplugin' Name="Test.aaxplugin" Vital='yes' KeyPath='yes' />
</Component>
</ComponentGroup>
</Fragment>
The problem is the upper casing of the folder IDs below INSTALL_FOLDER. Changing these to have some lower case characters fixed the issue. This seems to be due to upper case only IDs being treated differently.

wix installer "could not access network location"

I get the error "could not access network location \Common" when running the installer.
Any ideas will be much appreciated.
<Property Id="BINDIR">
<RegistrySearch Id='BinDirReg' Type='raw' Root='HKLM' Key='SOFTWARE\xxx' Name='AppDir' Win64='no'/>
</Property>
<Property Id="DATADIR">
<RegistrySearch Id='DataDirReg' Type='raw' Root='HKLM' Key='SOFTWARE\xxx' Name='DataDir' Win64='no'/>
</Property>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir" />
<SetDirectory Id="TESTBINFOLDER" Value="[BINDIR]\a\b\c" />
<SetDirectory Id="TESTDATAFOLDER" Value="[DATADIR]\a\b\c" />
<SetDirectory Id="TESTCOMMONDATAFOLDER" Value="[DATADIR]\Common" />
The value of the DATADIR property is empty so the value of TESTCOMMONDATAFOLDER is "\Common"
You really shouldn't be trying to define your Directory structure this way since on your very first install you'll try to set the TESTCOMMONDATAFOLDER to [DATADIR]\Common but there's no way your registry key exists in the registry.
You should define your Directory Structure as a default baseline. THere are several well-definied System Folder Properties for msis that you can use to define your default directory structure.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="CompanyName">
<Directory Id="BIN" Name="_bin" />
<Directory Id="DataDir" Name="Data" />
</Directory>
</Directory>
<Directory Id="AppDataFolder" >
<Directory Id="ProductName" />
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="ProductName"/>
</Directory>
</Directory>
Define your default structure this way. If you let the user set a custom install location, you can use a registry search to set the property for the directory and everything else will update nicely. for example,
<Property Id="INSTALLDIR">
<RegistrySearch
Id="InstallDirRegSearch"
Root="HKLM"
Key="SOFTWARE\ProductName"
Name="Path"
Type="raw"/>
</Property>
And this will set the INSTALLDIR to the custom location and all the BIN and DataDir folders will get updated with the new INSTALLDIR location. You can do a similar registry search to set directory locations for all other Directories. The plus side of doing it this way is that if these registry locations do not exist, you'll still use the default defined structure for your installation.

Wix Installer - how can I show the value of [Manufacturer] in the install path?

I'm trying to create an installer with a UI, using WiX.
My INSTALLFOLDER is set up using this:
<Directory Id="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="ManufacturerFolder"
Name="[Manufacturer]">
<Directory Id="INSTALLFOLDER"
Name="[ProductName]" />
</Directory>
</Directory>
</Directory>
In the <Product> section, I'm defining:
<UIRef Id="WixUI_InstallDir" />
<UIRef Id="WixUI_ErrorProgressText" />
<Property Id="WIXUI_INSTALLDIR"
Value="INSTALLFOLDER" />
When I run the installer and get to the Destination Folder panel, I see:
Install Service to:
C:\Program Files\[Manufacturer]\[ProductName]\
How can I make it evaluate the variables for display?
Note: if I leave them, and click Next, Install and Finish it works. It just looks bad.
Binder variables can make this very easy without needing to mess around defining preprocessor variables. It'd go a lot like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="ManufacturerFolder" Name="!(bind.property.Manufacturer)">
<Directory Id="INSTALLFOLDER" Name="!(bind.property.ProductName)" />
</Directory>
</Directory>
</Directory>
The !(bind.) syntax is documented in the Linker (light) topic in WiX.chm.
Define your variables in a config file.
For example, create a file named config.wxi containing the following:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define Manufacturer = "Company Name" ?>
<?define ProductName = "Product Name" ?>
</Include>
Then reference the variables in your .wxs file using $(var.Manufacturer) and $(var.ProductName).

Setting directory using RegistrySearch for not exist directory doesn't work

I am using RegistrySearch to set a property that is one of my directory and i see that when the registry value is of sub directory that doesn't exist than he value of the directory is not set, why is that?
In my case the ROLESDIR will be set to empty if the target directory doesn't exist (while the registry still point to it) --> the end result is that the the RoleDir will be installed directly under CONFDIR
<Property Id="ROLESDIR">
<RegistrySearch Id="ROLESDIRRegistry" Type="directory" Root="HKLM" Key="Software\DummyName\UCM" Name="ConfRolesDirectoryPath" />
</Property>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="SDIR">
<Directory Id="CONFDIR" Name="Conf">
<Directory Id="ROLESDIR" Name="Roles">
<Directory Id="RoleDir" Name="MyRole" />
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
Your question isnt very clear,
Can you give an example of the registry value.
I have used this in the past.
<Property Id="INSTALLDIR">
<RegistrySearch Id="INSTALLDIRRegistry" Type="raw" Root="HKLM" Key="Software\Manufacturer\Product" Name="InstallDir" />
</Property>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="ProductName">
This sets the INSTALLDIR to the location of the path in the registry value. I think in your case you are trying to set the path of a folder which already has a path defined to it by the wix code.
You might want to try something like this
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ROLESDIR" Name="Roles">
<Directory Id="RoleDir" Name="MyRole" />
</Directory>
<Directory Id="ProgramFilesFolder">
<Directory Id="SDIR">
<Directory Id="CONFDIR" Name="Conf" />
</Directory>
</Directory>
</Directory>
Hope that helps