WIX Writing user data into config file - wix

I would like to ask a WiX installer question. I created a working installer that does many things already. I still need to ask the user for some specific information (the GUI is already done), and write it into a config file.
From this snippet, I think I could use the INSTALLFOLDER global variable.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="IISROOT" Name='WebDir'>
<Directory Id="INSTALLFOLDER" Name="IVRDesigner">
</Directory>
</Directory>
</Directory>
This is the part, when I want to use that. This code is taken from a tutorial, should work well, if the source tag is filled properly. The ..\src\Web.config is just a dummy, so the code can compile. The default installed path for the web.config file will be C:\inetpub\wwwroot\myfolder, but the user can change this during the installation.
The question is: how could I use the global variable here, or what kind of solution, do you recommend?
Thanks in advance.
<Component Id="ConfigureWebConfig" Guid="*">
<File Id="Web.config" Name="MyConfigfile" Vital="yes" KeyPath="yes"
Source="..\src\Web.config" />
<util:XmlFile Id="AppConfigSetConnStr" Action="setValue"
Permanent="yes" File="[#Web.config]"
ElementPath="/configuration/connectionStrings/add[\[]#name='GeoIVRDesignerEntities'[\]]" Name="connectionString"
Value="data source=[DBSERVER];" />
</Component>

Under the Product tag I would add the properties that I want to be able to change in the config file like this:
<Property Id="BUILDRAN" Value="INSTALLER"/>
<Property Id="EMAIL_RECEIPIANT" Value="thisisnotme#notthere.com" />
Create the Fragment for the Directory Structure
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir" >
<Directory Id="BasicDir" Name="Dev_Home">
<Directory Id="BasicDirSuite" Name="TEST">
<Directory Id="INSTALLFOLDER" Name="DesignPatterns" />
</Directory>
</Directory>
</Directory>
</Fragment>
Declare another Fragment for the transformation of the config file
<util:XmlFile Id="AppConfigSetBuildRan" Action="setValue" Permanent="yes" File="[#App.config]"
ElementPath="/configuration/applicationSettings/MyApp.Properties.Settings/setting[\[]#name='BuildRan'[\]]/value"
Value="[BUILDRAN]" />
<util:XmlFile Id="AppConfigSetEmail" Action="setValue" Permanent="yes" File="[#App.config]"
ElementPath="/configuration/applicationSettings/MyApp.Properties.Settings/setting[\[]#name='TestValue'[\]]/value"
Value="[EMAIL_RECEIPIANT]" />
If you want you can create your own custom dialog to let the End user enter values for the properties [BUILDRAN] && [EMAIL_RECEIPIANT], or you could use the command line and set the properties with parameters
msiexec /i My.msi BUILDRAN=SuperDebug EMAIL_RECEIPIANT=you#home.com

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.

How do I tell wix to install a file in a directory set in a property?

I want to do the following where XLSTART is defined as:
<CustomAction Id="AssignXLSTART" Return="check" Execute="firstSequence" Directory ='XLSTART' Value='[AppDataFolder]\Microsoft\Excel\XLSTART'>
</CustomAction>
And then I have a subsequent CustomAction that calls some C# code that may change this value.
And then in the list of files to install I have:
<Directory Id="XlStartFolderId" Name="[XLSTART]">
<Component Id="ExcelMacro_xla" Guid="26D21093-B617-4fb8-A5E7-016493D46055" DiskId="1">
<File Id="ExcelXLA" Name="AutoTagExcelMacro.xlam" ShortName="XLMacro.xla" Source="$(var.srcFolder)\AutoTagExcelMacro.xlam"/>
</Component>
</Directory>
But the above puts it in the INSTALLDIR[XLSTART]. How do I get it to read this as a property?
You should be able to install to the userprofile directory you refer to like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="LocalAppDataFolder">
<Directory Id="Microsoft" Name="Microsoft">
<Directory Id="Excel" Name="Excel">
<Directory Id="XLSTART" Name="XLSTART">
<Component Id="ExcelAddIn" Feature="MyFeature" Guid="{11111-1111-GUID-HERE-YOURGUIDHERE}">
<File Source="C:\SourceFiles\MyAddin.xla" />
<RemoveFolder Id="Microsoft" On="uninstall" Directory="Microsoft" />
<RemoveFolder Id="Excel" On="uninstall" Directory="Excel" />
<RemoveFolder Id="XLSTART" On="uninstall" Directory="XLSTART" />
<RegistryValue Root="HKCU" Key="Software\MySoftware" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
I would suggest you use the per-machine xlstart folder instead - if it still exists. I am not sure it does. The the addin is loaded for every user on the box on every launch. Generally I prefer this. It has been ages since I looked at this, so this could have changed in newer Office versions - in fact I am sure it has, but the details are unclear to me.
System Folder Properties: There are a number of System Folder Properties that can be used in MSI files to specify installation location - LocalAppDataFolder is just one of them: https://learn.microsoft.com/en-us/windows/win32/msi/property-reference#system-folder-properties
Figured it out. You need to install to the INSTALLDIR and then use CopyFile
<!-- place it in C:\Program Files (x86)\Microsoft Office\Root\Office16\XLSTART\ -->
<Component Id="ExcelMacro_xla" Guid="26D21093-B617-4fb8-A5E7-016493D46055" DiskId="1">
<File Id="ExcelXLA" Name="AutoTagExcelMacro.xlam" ShortName="XLMacro.xla" Source="$(var.srcFolder)\AutoTagExcelMacro.xlam">
<CopyFile Id='CopyXlMacro' DestinationProperty='XLPATH' DestinationName='AutoTagExcelMacro.xlam'/>
</File>
</Component>

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 - Setting Install Folder correctly

I'm creating a program which is being installed by Wix, using VS 2010 and I've already got the product.wxs ready.
In my wxs file, I've got directory definitions which looks like this:
<SetDirectory Id="INSTALLFOLDER" Value="[WindowsVolume]Myapp" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLFOLDER" Name="Myapp">
<Directory Id="Myapp_Installer_Dir" Name="Myapp">
<Directory Id="BIN" Name="Bin" />
<Directory Id="ICONS" Name="Icons" />
</Directory>
</Directory>
</Directory>
And then I got these file installation definitions:
<DirectoryRef Id="Myapp_Installer_Dir">
<Component Id="INSTALLER_Myapp" Guid="{94F18477-8562-4004-BC6F-5629CC19E4CB}" >
<File Source="$(var.Myapp.TargetPath)" KeyPath="yes"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="BIN">
<Component Id="INSTALLER_Data" Guid="{545FB5DD-8A52-44D7-898E-7316E70A93F5}" >
<File Source="$(var.Data.TargetPath)" KeyPath="yes"/>
</Component>
...
And it continues in that manner. The files for the "ICONS" directory are defined as well.
I am also using the WixUI_InstallDir dialog set and I got these lines present as well:
<Property Id="WIXUI_INSTALLDIR" Value="Myapp_Installer_Dir" />
<UIRef Id="WixUI_InstallDir" />
The problem is when the user installs the program and changes the value of the installation folder, the files of the "Bin" and "Icons" are installed to their correct path, but the Myapp target is installed to a fix location which was defined at the start as the default installation path.
Why do only the bin and icon files installed to the correct folder the user wanted, but the myapp target does not?
I have finally figured out the problem.
After searching for a while, I came across this document:
WixUI_InstallDir Dialog Set
The relevant part: "The directory ID must be all uppercase characters because it must be passed from the UI to the execute sequence to take effect."
And as you can see in my code: "Myapp_Installer_Dir" does not meet this criteria.
After changing it to "MYAPPINSTALLERDIR", everything worked.
I'm not quite sure, but this is what I think has happened.
When you author a SetDirectory element, you basically add a custom action which sets a directory to the MSI database. As long as you do not specify the sequence it is executed in, it defaults to both, which means execute in both InstallUISequence and InstallExecuteSequence.
Now, when a user changes the installation directory in the wizard, this happens in the UI sequence. Obviously, when the installation enters the execute sequence, the value of INSTALLFOLDER is set to [WindowsVolume]Myapp as it was instructed.
So, you have to rework this somehow. Keep in mind the silent installation as well - there's only execute sequence there.
UPDATE instead of what you have, try something like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="WindowsVolume">
<Directory Id="INSTALLFOLDER" Name="Myapp">
<Directory Id="BIN" Name="Bin" />
<Directory Id="ICONS" Name="Icons" />
</Directory>
</Directory>
</Directory>
And let the user optionally change the INSTALLFOLDER as you do now.
Additionally to the pitfall with capital letters there is also an other one:
You have to mark the ID of the changeable directory as secure. (At least when the setup runs with admin rights.)
Related to Yonatan's answer with the directory ID MYAPPINSTALLERDIR you have to add this:
<Property Id="MYAPPINSTALLERDIR" Secure="yes" />
Related to the example WixUI_InstallDir in the WiX documentation you have to add this:
<Property Id="TESTFILEPRODUCTDIR" Secure="yes" />
Unfortunately this important fact is not mentioned in the WiX example.

Copy file from setup location to another location in wix on install

I have created an msi setup file which includes some files in a "Sample" folder which should be copied to a temp folder. Anybody suggest how to do this?
Something like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyVendor" Name="MyVendor">
<Directory Id="INSTALLDIR" Name="MyDir">
<Component Id="MyFileId" Guid="...G1...">
<File Id="MyFileId" Name="MyFile" Source="...blabla...\MyFile" KeyPath="yes" >
</File>
</Component>
<DirectoryRef Id="TARGETDIR">
<Component Id="MyFileCopyId" Guid="...G2...">
<RemoveFile Id="MyFileRemoveId" Name="MyFile" On="install" Directory="MyCopyDir" />
<CopyFile Id="MyFileCopyId" FileId="MyFileId" DestinationDirectory="MyCopyDir" />
</Component>
<Feature Id="MyFeature" ... >
<ComponentRef Id="MyFileId" />
<ComponentRef Id="MyFileCopyId" />
The important Xml element is CopyFile. You need to create a new component that is a copy of the first one (with different ids, guids, ... of course). Both components needs to be declared in a feature.
CopyFile element is your friend. You can nest it under the original File element a number of times, depending on how many times you need to copy it. Put the correct destination folder(s) and let Windows Installer do the rest.