How to set value of environment value based on install dir - wix

In a Wix installer xml file, when creating an environment variable, how can I set the value of the env var based on the install directory that the user selected?
Currently, I have something like this, and the part I'm missing is ???:
<Component Id='CompId' Guid='xxx'>
<File Id='ProgramEXE' Name='foo.exe' DiskId='1' Source='foo.exe' KeyPath='yes' />
<Environment Id='FooInstall' Action='set' Name='FOO_INSTALL' Value='???'/>
</Component>

The Environment table's Value column is of type Formatted. Directory table entries become properties during CostFinalize so therefore you can just say [DIRECTORYNAME] such as [INSTALLLOCATION].

Related

SourceProperty as Nested Directory in CopyFile

I want to copy two file from existing location to new location using WIX Installer.
INSTALLDIR and Destination Directory are already defined. And In SourceProperty for first I want to use INSTALLDIR\P\X\Y and In second I want to use INSTALLDIR\Q\X\Y
<ComponentGroup Id="aYML" Directory="INSTALLDIR">
<Component Id="CopyaYML" Guid="" Transitive="yes">
<CopyFile Id ="aYMLcopy" SourceProperty="INSTALLDIR\P\X\Y" SourceName="A.yml" DestinationProperty="Destination"/>
<CreateFolder/>
</Component>
</ComponentGroup>
<ComponentGroup Id="bYML" Directory="INSTALLDIR">
<Component Id="CopybYML" Guid="" Transitive="yes">
<CopyFile Id ="bYMLcopy" SourceProperty="INSTALLDIR\Q\X\Y" SourceName="B.yml" DestinationProperty="Destination"/>
<CreateFolder/>
</Component>
</ComponentGroup>
As \ is not allowed in WIX how to achieve this?
It has to be a property name, which has a limited character set of letters, numbers, and underscores. You could use a SetProperty custom action (type 19) to format a value using the directory ID and the file name, or even the [#fileId] property format, though that's not reliable in older versions of Windows Installer.
Before InstallFiles but after CostFinalize, you could do something like this:
<SetProperty Id="AYMLPATH" Before="InstallFiles" Sequence="execute" value="[ParentDirectoryId]A.yml" />
Though, it may be easier to just use the SourceDirectory attribute and specify the directory ID.
Copying files, though, can cause issues for some servicing scenarios. For example, if you copy files in a patch, the changes can't be rolled back. If the files are small, just duplicate the files. There are even tricks to duplicating the file records, but keeping a single file blob in a CAB, but is outside the scope of this answer.

Hot ti Install File just in the first time with WIX

I have a component
<Component Id="ProductComponent" Guid="7935315f-4242-4c7a-a02c-6fd256805356">
<CreateFolder/>
<File
Id="propFile"
Name="aaa.properties"
DiskId="1"
Source="$(var.Project.TargetDir)"
Vital="yes"
KeyPath="yes" ></File>
<?endif?>
</Component>
I want to copy the file just on install , not upgrade.
But I can't find how to do it.
Any idea?
Have you tried using Condition element. I think you can provide a Condition inside Component element to check whether product is already installed or not. If not installed, then create file.
<Component Id="ProductComponent" Guid="7935315f-4242-4c7a-a02c-6fd256805356">
<Condition> NOT Installed </Condition>
<CreateFolder/>
<File
Id="propFile"
Name="aaa.properties"
DiskId="1"
Source="$(var.Project.TargetDir)"
Vital="yes"
KeyPath="yes" ></File>
</Component>
This is a weak spot of MSI (which WiX uses).
MSI installs a file
User modifies the file
MSI goes to install the file. Should it:
a) overwrite and lose user data
b) not overwrite and lose new applciation data
c) merge --- MSI doesn't support this.
If the user data is only one or few attributes there are tricks with custom actions to harvest the user data and reapply it but this is very tricky stuff.
IMO, the best way to approach this is never keep user data in a file installed by the installer. Take app.config appSettings element as an example. It was an atttribute that allows you to extend the file with another file that overrides the settings in the first file. Using this pattern the installer can lay down the app config and the application can create the override file and everything just works because MSI doesn't have to deal with the problem at all.

Why xmlfile action happens even the file has no other changes in wix?

We are having a web.config file installed as part of our MSI.
<Component Id="Alert" Guid="Some valid GUID">
<File Id="Web.config" Source="..\..\..\..\<Somevalidpath>\Web.config" KeyPath="yes" />
<File Id="Global.asax" Source="..\..\..\..\<Somevalidpath>\Global.asax" KeyPath="no" Name="Global.asax" />
<util:XmlFile Id="SetKey_ServiceURL"
Action="setValue"
ElementPath="//appSettings/add[\[]#key='URL'[\]]/#value"
Value="[SERVICEURL]"
File="[#Web.config]"
SelectionLanguage="XPath"
Sequence="1" />
</Component>
In that web.config file we are upgrading a URL which is passed as a parameter to Msi via the Parameter Name SERVICEURL.
After we released our product ,due to issues we had to do minor upgrade . We decided to go with Msp rather than Msi. Now though the Web.config file has no changes , if we did not pass the parameter SERVICEURL it changes the Web.config file with empty value.
We are forced to pass the SERVICEURL again while installing the Msp though that file has no changes.
Is it possible to avoid this ? We do not want to update the URL unless there is no change.
It might not be obvious, but that change is a custom action, and it runs during the patch install as well. You need something like this:
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/util-XmlFile-conditionally-set-value-td3900952.html
where there is a condition on the CA. In your case, the condition PATCH is set during a patch, so you could use NOT PATCH as the condition.
Otherwise, use the WiX 'remember property" pattern and the property value will be preserved and restored.

Install component conditionally in Wix

We have a Wix project for our Installer. Is it possible to check if a file exists?
Basically, for some of our config files, we want to pass in the path of the file that is actually not present in our installer script but pass in the path of the file to a public property on command line.
In this case we want the config file component to use this passed in config file during the installation instead of the default config file.
Is this possible?
I have tried something like this:
<?if FileExist([PORTALCONFIGPATH])?>
<File Id='webConfig' Name='web.config' DiskId='1' Source='[PORTALCONFIGPATH]' KeyPath='yes'/>
<?else?>
<File Id='webConfig' Name='web.config' DiskId='1' Source='web.config' KeyPath='yes'/>
<?endif?>
Someway to check that the passed in file name exists then install the passed in file otherwise use the default file.
The WiX FileSearch, DirectorySearch, Condition, and CopyFile elements are what you are looking to use. Create a property, when executing the msi if the property is set then the DirectorySearch and FileSearch elements will look in the path for that property, setting another property (MYFILEEXISTS for example) then if MYFILEEXISTS CopyFile will run with the path.

WIX one or more Conditional Component with predefined Variables

Hi based on Environments(UAT,TEST,DEV,PROD) and Server Specific(Server1,Server2..) I am filtering the config files.
<Component Id="cmp39F4D3AA1248B5FE5EB2F92D189B27E1" Directory="dirCFCE6D07D3330FE628276777F0488B18" Guid="{56788F77-A729-47CE-BBA4-9D7D7F175536}">
<File Id="fil10B3B7732D0DDBD4AA773E0B7F34D092" KeyPath="yes" Source="$(var.SDirect.B2CWeb.ProjectDir)Web.ProdBuild.Web1.config.xml" >
<CopyFile Id="SCopy_ConfigPROD1" DestinationProperty="DestFilesWebsiteFolder" DestinationName="Web.config" />
</File>
<Condition> <![CDATA[ENVPROPERTY~="PROD"]]></Condition>
</Component>
The Above component works fine; the ENVPROPERTY Property value is set through command line when Installing by MSIEXEC.
But When I change the above statement as below doesn't work where the Installer need to detect the computername or Servername where it gets installed and based on that the installer must make sure to deploy the above component or not.
<Component Id="cmp39F4D3AA1248B5FE5EB2F92D189B27E1" Directory="dirCFCE6D07D3330FE628276777F0488B18" Guid="{56788F77-A729-47CE-BBA4-9D7D7F175536}">
<File Id="fil10B3B7732D0DDBD4AA773E0B7F34D092" KeyPath="yes" Source="$(var.SDirect.B2CWeb.ProjectDir)Web.ProdBuild.Web1.config.xml" >
<CopyFile Id="SCopy_ConfigPROD1" DestinationProperty="DestFilesWebsiteFolder" DestinationName="Web.config" />
</File>
<Condition> <![CDATA[ENVPROPERTY~="PROD" AND ComputerName~="Server1"]]></Condition>
</Component>
Can any one help in setting the conditional statement which satisfies ENVPROPERTY="PROD" and ComputerName="Server1" ie the servername(Machine) the MSI package gets installed. So that above components gets deployed and not skipped when package gets deployed.
Thanks in advance
Public Properties only can be used in command line. All letters should be in upper case for public properties. Use ComputerName property as COMPUTERNAME like the other one.