How to modify the component .xml file with utils:XmlFile using WIX? - wix

I am trying to create an installer which also installs the xml-file depending on input values, entered in separate dialog. Here
</Component>
<Component Id="ConfigXMLDocument">
<File Id ="Config" KeyPath="yes" DiskId="1" Vital ="yes" Source="$(var.Server.ProjectDir)config.xml"/>
<CreateFolder Directory="INSTALLFOLDER">
<util:PermissionEx User="Users" ChangePermission="yes" GenericAll="yes"/>
</CreateFolder>
<util:XmlFile ElementPath ="root/Server/servername" File ="[INSTALLFORDER]config.xml" Sequence="1" Id ="SERVERNAME"
Action ="setValue" Value ="THIS VALUE IS NOT BEING SET" SelectionLanguage="XPath"/>
<util:XmlFile ElementPath ="root/Server/listenport" File ="[INSTALLFORDER]config.xml" Sequence="2" Id ="PORT"
Action ="setValue" Value ="THIS ONE EITHER"/>
</Component>
The problem is that there are no errors and all the paths are resolved correctly, but the installed file remains the same as original.
If I try to change any other XML-file, It works, but not the one installed.
I found simmilar issues online, but no answers fixed mine.
Is it possible that XmlFile is just changing file before file is installed? And what else can cause such problem?

It appeared to be not one, but two issues.
The first one was to use FIle ID instead of path, so I replaced this
File ="[INSTALLFORDER]config.xml"
with this:
File ="[#Config]"
But It still didn`t work, during the installation appeared an error that the installer cannot find the file config.xml, so i changed the InstallExecuteSequence to this:
<InstallExecuteSequence>
<Custom Action="SchedXmlFile" After="InstallFiles" />
</InstallExecuteSequence>
UPD. This still did not work fine. WIX could not open the file with error:
Failed to open XML file path/config.xml, system error: -2147024786
The error appeared to be that wix cannot recognize the BOM in the XML file for some reason:
<?xml version"1.0" encoding="UTF-8" ?>
So i just removed it.
Hope this helps.

Related

Failed to open XML file - Wix unable to update appsettings.json

I am using Wix to create MSI installers. My requirement is to pass parameters while installing msi from the command line and update' theappsettings.json` with the values passed.
To achieve this, I have added below property and component.
<Property Id="ApplicationLog.pathFormat" />
<Component Id="config" Guid="*">
<File Id="appconfig" Source="$(var.BasePath)\appsettings.json" KeyPath="yes" Vital="yes"/>
<util:XmlFile
Id="_pathFormat_" File="$(var.BasePath)\appsettings.json"
Action="setValue"
Name="pathFormat" Value="[pathFormat]"
ElementPath="/ApplicationLog/Serilog/WriteTo/Args/"
Sequence='1' />
</Component>
I have passed the values as follow while installing
C:\work\Installer\bin\Debug>MyService-Debug-x86.msi pathFormat="value1"
But I get below error
Failed to open XML file ....\Installer\bin\Debug\netcoreapp2.1\win-x86\publish\appsettings.json. system error -2147024786
Additional Information
There was ICE30 error,
ICE30: The target file 'l-racj8d.jso|appsettings.json' is installed in '[ProgramFilesFolder]\MyService\' by two different components on an LFN system: 'config' and 'cmpF82FCA80BBAF44D285C97F10993DEEE6'.
Which resolved by changing the ICE validation-> Suppress ICE validation
But why installer unable to open the json app settings? I am running the installer in administrator mode.
Update
I have changed $(var.BasePath) to '[INSTALLDIR]'
<Component Id='config' Guid='*'>
<File Id='jsonconfig' Source='[INSTALLDIR]appsettings.json' KeyPath="yes" Vital="yes"/>
<util:XmlFile Id='xpathFormat' File='[INSTALLDIR]appsettings.json'
Action='setValue' Name='pathFormat' Value='[ApplicationLog.pathFormat]'
ElementPath='/ApplicationLog/Serilog/WriteTo/Args/' Sequence='1' />
</Component>
But I am getting
The system cannot find the file '[INSTALLDIR]appsettings.json'.
Is it because appsettings.json is not yet copied to [INSTALLDIR]?? If yes, then how to achieve this?

wix install xml file, edit file and copy to another location

I am trying to install a XML file(Tomcat context file) and copy the file to another location inside Tomcat\config\Catalina\ using WiX.
Before copying the file to Tomcat, I want to edit some values in the Context xml. Here, I have modified the xml using the tag from WixUtilExtension.
Below is what I have Done:
<SetProperty Id="CopyLocation" Value="[%CATALINA_HOME]\conf\Catalina\" Before="AppSearch" Sequence="execute"/>
<DirectoryRef Id="INSTALLDIR">
<Directory Id="dirA99A3925C98F7E949CF98F783959A0E0" Name="MyInstallFolder">
<Component Id="cmp318E197D1FB960F5622BEB6879276359" Guid="{FFF02817-FA29-40B7-927A-E943C08A8774}">
<File Id="fil6674D3AD50416393E3C992B211173485" KeyPath="yes" Source="$(var.installfolder)\MyContext.xml" />
<util:XmlFile Id="DocBase" Action="setValue" Permanent="yes" File="[#fil6674D3AD50416393E3C992B211173485]"
ElementPath="//Context" Name="docBase"
Value="[INSTALLDIR]InstallFolder" SelectionLanguage="XPath" Sequence="1"/>
<CopyFile Id="Copy_File" DestinationProperty="CopyLocation" DestinationName="MyContext.xml" FileId="fil6674D3AD50416393E3C992B211173485"/>
</Component>
</Directory>
</DirectoryRef>
Below is the XML Sample:
<Context path="/XERService" docBase="NoValue">
</Context>
The issue is that I am able to modify the file that is installed to the installation path but the file which is copied to the Tomcat doesnot have the changes.
This is because the default sequence for the DuplicateFiles action (the MSI action that maps to CopyFile) happens before the SchedXmlFiles action. You should be able to override this by specifying the following:
<InstallExecuteSequence>
<Custom Action="SchedXmlFile" Before="DuplicateFiles" />
</InstallExecuteSequence>

LGHT1076 / LGHT1076: Install a data file to localappdata

Using WiX, a file can be installed to ProgramFiles using the following:
<DirectoryRef Id="ApplicationBinDirectory">
<Component ...>
<File Id="..." KeyPath="yes" Source="..." />
</Component>
</DirectoryRef>
Now I want to do the same, but the target is a folder in local application data. The file really belongs there according to http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
<!-- this is the folder in %LOCALAPPDATA% -->
<Directory Id="LocalAppDataFolder">
<Directory Id="ApplicationLocalAppDataDirectory" Name="my folder name"/>
</Directory>
<DirectoryRef Id="ApplicationLocalAppDataDirectory">
<File Id="fil" KeyPath="yes" Source="..." />
</DirectoryRef>
But I get the following error and warning now:
installer.wxs(63) : error LGHT0204 : ICE38: Component ApplicationConfiguration installs to user profile. It must use a registry key under HKCU as its KeyPath, not a file.
installer.wxs(64) : warning LGHT1076 : ICE91: The file 'fil' will be installed to the per user directory 'ApplicationLocalAppDataDirectory' that doesn't vary based on ALLUSERS value. This file won't be copied to each user's profile even if a per
machine installation is desired.
Adding RegistryValue and RemoveFolder as I have to do it for start menu shortcuts doesn't change the message.
I'm kind of lost here. How do I install a file to local appdata? Please note that I want to install only 1 file there, in addition to the usual setup in program files.
This should help. It shows adding a registry key item to be the keypath:
http://nofoe.blogspot.com/2008/12/wix-it-must-use-registry-key-under-hkcu.html

In Wix, how can I avoid hardcoding a file source for a file that already exists in the installation directory?

In my .wxs file, I have the following file declaration. This file already exists in the installation directory. It is not being copied from the source directory. I need to update it using util:XmlConfig during the install. The XmlConfig part is working.
<File Id="AppConfig" Name="Dynamics.exe.config" Source="C:\Program Files (x86)\Microsoft Dynamics\GP2010\Dynamics.exe.config" />
The problem is I can't assume the file is always going to exist in that same location. I'd really like to simply reference it like so:
<File Id="AppConfig" Name="[#INSTALLDIR]\Dynamics.exe.config" />
However, that fails with the following message:
> light.exe ....
The system cannot find the file 'SourceDir\....\[#INSTALLDIR]\Dynamics.exe.config'
How can I say "the file already exists in the installation directory, use that file during the installation, and do not validate for it now"?
Directories are available with bracket notation as though they were regular properties. If you don't need to install the Dynamics.exe.config but just access it with XmlConfig elements, you can simply reference that directory and don't need to bother with the File element:
<Component Id="Dynamics.exe.config" KeyPath="yes" Guid="*">
<util:XmlConfig Id="Dynamics.exe.config.XmlConfig1"
On="install"
Action="..."
File="[INSTALLDIR]\Dynamics.exe.config"
...
/>
<util:XmlConfig Id="Dynamics.exe.config.XmlConfig2"
On="install"
Action="..."
File="[INSTALLDIR]\Dynamics.exe.config"
...
/>
</Component>

Conditionally install files based on Command Line Argument during WIX Install

I am wanting to install files during a wix install conditionally whether a command line parameter has been set
e.g. I have the following file, which only installs if a DEBUG flag has been set
<Component Id="file.pdb" Guid="SOME-GUID">
<Condition>DEBUG</Condition>
<File Id="file.pdb" Source="file.pdb" KeyPath="yes" Vital="no" />
</Component>
I have added the DEBUG property and read it in from the command line. The File never installs though, I am perplexed as to why?
Solved the issue. Below is an explanation of what I was doing wrong and what I did to solve it
I had created an installer (.msi) and was using the following cmd line args to start it up
msiexec -i prog.msi DEBUGPROPERTY=True
I had several merge modules with components which would install depending on whether this property was set which were getting the property injected into them like so...
<Merge
Id="SomeID"
Language="1033"
SourceFile="Module.msm"
DiskId="1">
<ConfigurationData
Name="debugProperty"
Value="[DEBUGPROPERTY]" />
What I was missing was in the merge modules (.msm) i needed the following code
<Configuration Name='debugProperty' Format='Text' DefaultValue='[DEBUGPROPERTY]'/>
<Substitution Table='CustomAction' Row='setDebugProperty' Column='Target' Value='[=debugProperty]'/>
<CustomAction Id='setDebugProperty' Property='DEBUGPROPERTY' Value='[DEBUGPROPERTY]'/>
<InstallExecuteSequence>
<Custom Action='setDebugProperty' Before="LaunchConditions">1</Custom>
</InstallExecuteSequence>
This allowed me to access the property DEBUGPROPERTY inside this module so i could restrict whether a file was installed at install time or not, like so
<Component Id="File.pdb" Guid="SOME-GUID">
<Condition>DEBUGPROPERTY</Condition>
<File Id="File.pdb" Source="File.pdb" KeyPath="yes" Vital="no" />
</Component>
This now works, and allows me to install .pdb files during an install if i include this argument.