WiX nesting child directories under installation directory - wix

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.

Related

How to install self signed SSL cert into store from Wix Installer?

I could not find any documentation on how to do this for the current version of Wix Toolset (3.11.1.2318).
Given I have a cert.cer file in my SourceDir and INSTALLDIR how do I put it in the Windows "Trusted Root Certification Authorities" store on install?
EDIT:
So I already read the linked answer, its from 2012! and uses Custom Actions. Is there not a better way? I also read: http://www.davidwhitney.co.uk/Blog/2009/02/11/installing-certificates-using-wix-windows-installer-xml-voltive/ which does not use Custom Actions, so am confused is there a better way yet or not?
This worked for me, hopefully helpful to someone in the future:
<Binary Id="ClientCertBinary" SourceFile="certificate-client.cer" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompany" Name="My Company">
<Directory Id="INSTALLDIR" Name="MyApp">
<Component Id="ClientCertComponent" Guid="YOURGUID-2F37-45A7-88DC-C2A7EAD41F96">
<CreateFolder />
<iis:Certificate Id="ClientCert"
Name="CertName"
StoreName="root"
StoreLocation="localMachine"
Request="no"
Overwrite="yes"
BinaryKey="ClientCertBinary" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id="Complete" Title="MyApp" Level="1">
<ComponentGroupRef Id="AllPublishFiles" />
<ComponentRef Id="ClientCertComponent" />
</Feature>
Thanks to all those who helped.

WIX 3.8 installer: Add files to a pre-existing folder

How would I install files directly into a pre-existing folder on the user's computer? All documentation I read only explains creating a custom INSTALLDIR.
Eg. c:\ProgramFiles(x86)\ExampleFolderA\ExampleFolderB\InstalledFile.exe
You should first define the directory structure:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="ExampleFolderAId" Name="ExampleFolderA">
<Directory Id="ExampleFolderBId" Name="ExampleFolderB" />
</Directory>
</Directory>
</Directory>
Note that the definition above does NOT create directories when the installation runs. In order for the directories to be actually "created" you have to either place files there (using Component elements), or explicitly state that the directory is empty.
Something like this:
<DirectoryRef Id="ExampleFolderAId">
<Component Id="SampleComponent" Guid="GUID-GOES-HERE">
<File Id="SampleFile" Source="C:\readme.txt" KeyPath="yes" />
</Component>
</DirectoryRef>
or
<DirectoryRef Id="ExampleFolderBId">
<Component Id="EmptyFolderComponent" Guid="GUID-GOES-HERE">
<CreateFolder />
</Component>
</DirectoryRef>
Hope you get the idea.

Wix creates an application data directory which is read only

I'm creating a folder structure in WiX in the following manner:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MyApp">
</Directory>
</Directory>
<Directory Id="CommonAppDataFolder">
<Directory Id="CONFIGFOLDER" Name="MyAppConfig">
<Directory Id="Configdir1" Name="Configdir1">
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="MyApp"/>
</Directory>
</Directory>
I'm then populating these directories later on using Component tags like this:
<ComponentGroup Id="ProductConfiguration" Directory="CONFIGFOLDER">
<Component Id="ConfigFile1" Guid="*">
<File Id="ConfigFile1.xml" Name="ConfigFile1.xml" Source="..\Configuration\ConfigFile1.xml" Vital="yes" KeyPath="yes" DiskId="1"/>
</Component>
<Component Id="ConfigFile2" Guid="*">
<File Id="ConfigFile2.xml" Name="ConfigFile2.xml" Source="..\Configuration\ConfigFile2.xml" Vital="yes" KeyPath="yes" DiskId="1"/>
</Component>
<Component Id="ConfigFile3" Guid="*">
<File Id="ConfigFile3.xml" Name="ConfigFile3.xml" Source="..\Configuration\ConfigFile3.xml" Vital="yes" KeyPath="yes" DiskId="1"/>
</Component>
</ComponentGroup>
My problem is this: WiX creates the Configuration directory (CommonAppDataFolder/MyAppConfig) as a read only folder. Since it's full of application data, users need to be able to modify its contents without having admin privileges. I can create other folders in the CommonAppDataFolder programmatically, which do not require admin privileges.
How do I set the write privileges for my folder in WiX?
Turns out that the answer looks something like this:
<Directory Id="MYFOLDER" Name="My folder name">
<Component Id="MyFolderComponent" Guid="*">
<CreateFolder Directory="MYFOLDER">
<Permission User="Everyone" GenericAll="yes" />
</CreateFolder>
</Component>
</Directory>
CommonAppDataFolder is a per-machine store and so requires elevated privileges to write to. If you want a per-user store, use the AppDataFolder or LocalAppDataFolder directory properties instead.

WiX company folder not created

I have this fragment to define my directory structure:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="COMPANYFOLDER" Name="MyCompany">
<Directory Id="APPLICATIONFOLDER" Name="HDSS.Net">
<Directory Id="EN" Name="en"/>
</Directory>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop"/>
</Directory>
</Fragment>
I have this component group with my application components:
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="APPLICATIONFOLDER">
....
</ComponentGroup>
</Fragment>
in my feature definition I refer to this group:
<Feature Id="ProductFeature" Title="HDSS.Net" Level="1" ConfigurableDirectory="APPLICATIONFOLDER">
<ComponentGroupRef Id="ProductComponents" />
...
<\Feature>
My problem is that upon installation only the application folder 'HDSS.Net' is created in Program Files and the application folder is not created inside of the 'MyCompany' folder as I would have expected. How can I ensure that this happens?
Thank you.
The setup code you provided thus far looks correct.
Some other part of your installation must be changing APPLICATIONFOLDER so that it ends up resolving to [ProgramFilesFolder]HDSS.Net. Search around for other references to APPLICATIONFOLDER.
Alternatively, take a look at a verbose log file. It should show you when APPLICATIONFOLDER is being overridden.

WiX merge module dependencies

I have an issue with some existing installers which I have repeated in a simple test case as follows:
Installer1 installs App1 and LibraryA(v1).
Installer2 installs App2, LibraryA(v2) and LibraryB. LibraryA(v2) requires LibraryB, which is why LibraryB is now installed. LibraryA(v1) had no such dependency. LibraryA(v2) should overwrite LibraryA(v1).
If I run Installer1 then Installer2, then uninstall Installer2, LibraryB gets removed, but LibraryA remains at v2 (sensible - I wouldn't expect it to revert to a prior version).
Forgetting my existing problem and imagine I was starting from scratch, how would you suggest I construct my WiX project to cope with such a situation? In my case, all of the libraries are defined as merge modules - something I'm not in a position to change (wixlibs are out of the question).
I have tried, to no effect, to use a Dependency element to create a dependency between the LibraryA(v2) merge module and the LibraryB merge module - it just seems to issue a linker warning if I forget to reference LibraryB in the installer, rather than creating an actual dependency.
The .wxs scripts in my test case look something like this (they all install to the same folder for ease of testing):
LibraryA(v1).wxs:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Component Id="LibraryAComponent" Guid="d98dd742-c3d3-4aee-8d84-87f2b3c837dc">
<File Source="v1\LibraryA.dll" />
</Component>
</Directory>
</Directory>
LibraryA(v2).wxs:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Component Id="LibraryAComponent" Guid="d98dd742-c3d3-4aee-8d84-87f2b3c837dc">
<File Source="v2\LibraryA.dll" />
</Component>
</Directory>
</Directory>
<Dependency RequiredId="LibraryBMergeModule.DD524F28_EAE0_47B8_A895_3AF2F7A7361A" RequiredLanguage="1033"/>
LibraryB.wxs:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Component Id="LibraryBComponent" Guid="46e6e0da-2a99-4f0d-bed2-e764e16b9eed">
<File Source="LibraryB.dll" />
</Component>
</Directory>
</Directory>
App1.wxs:
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" DiskId="1" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="WiXTest" Name="WiXTest">
<Merge Id="LibraryAv1" Language="1033" SourceFile="LibraryAv1.msm" />
<Component Id="App1Component" Guid="93D11AFF-5307-4355-B261-0096775B6A89">
<File Source="App1.exe" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="Libraries" Title="Shared Files" Level="1">
<MergeRef Id="LibraryAv1" />
</Feature>
<Feature Id="App" Title="Application" Level="1">
<ComponentRef Id="App1Component" />
</Feature>
App2.wxs:
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" DiskId="1" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="WiXTest" Name="WiXTest">
<Merge Id="LibraryB" Language="1033" SourceFile="LibraryB.msm" />
<Merge Id="LibraryAv2" Language="1033" SourceFile="LibraryAv2.msm" />
<Component Id="App2Component" Guid="173C71B6-E403-4AC1-894D-06799C6782A4">
<File Source="App2.exe" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="Libraries" Title="Shared Files" Level="1">
<MergeRef Id="LibraryB" />
<MergeRef Id="LibraryAv2" />
</Feature>
<Feature Id="App" Title="Application" Level="1">
<ComponentRef Id="App2Component" />
</Feature>
I'm guessing that this is entirely the wrong way to go about things and am looking for some pointers to bring me back on track. It feels like you need to have a PhD in Windows Installer in order to use WiX correctly.
I am no WIX expert but yes for MSI you need at least a PhD. At first you should know the rules about MSI components:
What Every Developer Should Know About MSI Components
From painful experience I do know that if several MSIs bring in the same components it is no good. If possible I would strive for the single source principle so that your libs are installed always by the same MSI (let it be a infrastructure MSI). Your application MSIĀ“s then simply check if the infrastructure has been installed and that was it.
Coming back to your question what you should do with your merge modules. I would create for each merge module an extra msi (yes customers do not like crowed installed software catalogs) to be sure that if you are in need to service the libraries you have full freedom.
I do not know your software structure but it could be that you will need LibraryA v1 and v2 at the same time so you should think about deploying your libraries to the WinSxS cache or if they are managed the GAC. Or you come up with something similar in your folder structure or file name convention.