I want to install certain set of files based on OS version and another set of files based on another OS version using wix file - wix

I need to install one set of files based on OS version and another set if some other OS is there,I have written a condition also but that condition doesn't work properly .
<Component Id="actionBin_Win7" Guid="6b73cbe1-4017-48d7-9cdc-784517b2d7a9" DiskId="1">
<Condition><![CDATA[(VersionNT >= 600)]]></Condition>
<File Id="file30" Name="AXINTE_2.DLL" LongName="AxInterop.MSTSCLib.dll" src="$(var.agentroot)\bin\AxInterop.MSTSCLib_Win7.dll" />
<File Id="file31" Name="ZENRDP_2.EXE" LongName="ZENRdpClient.exe" src="$(var.agentroot)\bin\ZENRdpClient_Win7.exe" />
<File Id="file32" Name="INTERO_2.DLL" LongName="Interop.MSTSCLib.dll" src="$(var.agentroot)\bin\Interop.MSTSCLib_Win7.dll" />
</Component>
<Component Id="actionBin" Guid="7388F2C9-5CDD-49a8-80F7-7DF5829AE87E" DiskId="1">
<Condition><![CDATA[(VersionNT < 600)]]></Condition>
<File Id="file10" Name="AXINTE_1.DLL" LongName="AxInterop.MSTSCLib.dll" src="$(var.agentroot)\bin\AxInterop.MSTSCLib.dll" />
<File Id="file11" Name="msrdp.ocx" LongName="msrdp.ocx" SelfRegCost="1" src="$(var.agentroot)\bin\msrdp.ocx" />
<File Id="file12" Name="ZENRDP_1.EXE" LongName="ZENRdpClient.exe" src="$(var.agentroot)\bin\ZENRdpClient.exe" />
<File Id="file13" Name="INTERO_1.DLL" LongName="Interop.MSTSCLib.dll" src="$(var.agentroot)\bin\Interop.MSTSCLib.dll" />
<File Id="file14" Name="shortcut.vbs" LongName="shortcut.vbs" src="$(var.agentroot)\bin\shortcut.vbs" />
</Component>
Feature :
<Feature Id="AllComponents" Title="AllComponents" Level="1">
<ComponentRef Id="actionBin" />
<ComponentRef Id="actionBin_Win7" />
</Feature>
Any idea what is going wrong here? Even when OS is windows 7, MSI takes files which I intend for WinXP...
Thanks in advance.

As far as i know about WIX, CDATA is used of ASCII comparison and not for integer comparison.
You can use custom action to compare OS version and then assign true or false value to some session variable and then you can use that session variable in wxs file.

Related

How that ININExtension.Tier*Name is being picked up in WXS file

I was trying to give a dynamic file name based on its version for WIX Component file as given below. But I would like to know how the dynamic file name will be picked up in this. Got some reference from some other WXS file but not clear how it is working. Even the file is still not working properly.
Tried this : File - icsharpcode.sharpziplibmarquee_w64.d.wxs
<?xml version='1.0' encoding='UTF-8'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:inin='http://www.inin.com/i3WixExtensions'>
<Fragment>
<DirectoryRef Id='IWP_MARQUEE'>
<Component Id='icsharpcode.sharpziplibmarquee_w64.d' Guid='YOUR-GUID' >
<File Name='icsharpcode.sharpziplib-w64r-$(ININExtension.TierVersionEicName).dll' ReadOnly='no' KeyPath='yes' Id='icsharpcode.sharpziplib-w64r.dll' Source="FindFirstInDirs(TIER_ROOT_EIC, pub/gen/bin/w64/ICSharpCode.SharpZipLib-w64r-$(ININExtension.TierVersionEicName).dll)" />
<?ifdef DebugBuild?>
<File Name='icsharpcode.sharpziplib-w64d-$(ININExtension.TierVersionEicName).dll' ReadOnly='no' Id='icsharpcode.sharpziplib-w64d.dll' Source="FindFirstInDirs(TIER_ROOT_EIC, pub/gen/bin/w64/ICSharpCode.SharpZipLib-w64d-$(ININExtension.TierVersionEicName).dll)" />
<?else ?>
<File Name='icsharpcode.sharpziplib-w64r-$(ININExtension.TierVersionEicName).pdb' ReadOnly='no' Id='icsharpcode.sharpziplib-w64r.pdb' Source="FindFirstInDirs(TIER_ROOT_EIC, pub/gen/bin/w64/ICSharpCode.SharpZipLib-w64r-$(ININExtension.TierVersionEicName).pdb)" />
<?endif ?>
</Component>
</DirectoryRef>
</Fragment>
</Wix>
Must read files like ICSharpCode.SharpZipLib-w64r-23-1.dll, ICSharpCode.SharpZipLib-w64d-23-1.dll, ICSharpCode.SharpZipLib-w64r-23-1.pdb. Where 23-1 is 2023R1 (dynamically updating based on release version)

Conditionally install file based on a property in wix

I want to install a file only if a property is set to "yes". Is this the correct way to do it?
The property is ExcelInstalled and is set to "yes" or "no".
<Directory Id="XlStartFolderId" Name="[XLSTART]">
<Component Id="ExcelMacro_xla" Guid="26D21093-B617-4fb8-A5E7-016493D46055" DiskId="1">
<Condition>ExcelInstalled="yes"</Condition>
<File Id="ExcelXLA" Name="AutoTagExcelMacro.xlam" ShortName="XLMacro.xla" Source="$(var.srcFolder)\AutoTagExcelMacro.xlam"/>
</Component>
</Directory>
Figured it out - it goes inside the File node:
<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">ExcelInstalled="yes"</File>
</Component>
</Directory>

WiX installer: can we add a new element in web.config using a patch when it is set to NeverOverwrite=yes in its initial msi

I am working on a web application. the Web.config file is set to NeverOverwrite (=yes) in its initial installation. Now i need to add DBproviderfactories like below. Can i add this entire block using XmlFile in a patch.msp? I do not want to write a custom action. All I need is to add this block in the web.config. Any suggestion here is appreciated.
<system.data>
<DbProviderFactories>
<!-- Remove in case this is already defined in machine.config -->
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="Oracle Data Provider for .NET" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
Sample: Maybe try this:
https://github.com/glytzhkof/WiXUpdateXmlFile
Below is the gist of it - please use the sample above for testing. The markup below is just for illustration.
Set the XML file both permanent and never overwrite.
See inline instructions in the sample above for testing.
Check what happens on uninstall - this markup will remove the entries it added.
<!-- Set app.config permanent and never overwrite to yes -->
<Component Feature="ProductFeature" NeverOverwrite="yes" Permanent="yes">
<File Source="app.config" />
</Component>
<!-- The XML update -->
<!-- Use a NEW GUID here, do not go live with this one -->
<Component Id="XmlFileUpdate" Guid="{00000000-0000-0000-0000-7405EED51B57}" Feature='ProductFeature'>
<!--Create New Element-->
<util:XmlFile Id='XmlSettings1' File='[INSTALLFOLDER]app.config' Action='createElement' Name='MyConfig' ElementPath='//configuration' Sequence='1' />
<!--Set New Value-->
<util:XmlFile Id='XmlSettings2' File='[INSTALLFOLDER]app.config' Action='setValue' Name='newVersion' Value='6.6.8' ElementPath='//configuration/MyConfig' Sequence='2' />
<!--Set New Value-->
<util:XmlFile Id='XmlSettings3' File='[INSTALLFOLDER]app.config' Action='setValue' Name='Server' Value='Pusevov' ElementPath='//configuration/MyConfig' Sequence='3' />
<!--Update Existing Value, Existing Element-->
<util:XmlFile Id='XmlSettings4' File='[INSTALLFOLDER]app.config'
Action='setValue' Name='newVersion' Value='7.7.7' ElementPath='//configuration/ExistingConfig/bindingRedirect' Sequence='4' />
<CreateFolder />
</Component>
</Directory>
</Directory>
Link:
Added new application setting to app.config but MSI won't install it (doesn't overwrite)

string compare in condition

when I get my achitecture type like this:
<Property Id="PLATTFORM">
<RegistrySearch Id="myRegSearchPalttform"
Root="HKLM"
Key="SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Name="PROCESSOR_ARCHITECTURE"
Type="raw">
</RegistrySearch>
</Property>
and want to check if it is "AMD64" like this:
<?define myPlattform = [PLATTFORM] ?>
<?if $(var.myPlattform) = AMD64 ?>
some stuff
<?else ?>
some stuff
<?endif ?>
it fails.
When I set the value static:
<?define stest = AMD64 ?>
<?if $(var.stest) = AMD64 ?>
it goes in true scope. So why is the value from the registry(there is the value AMD64) not identical with my proof string????
Tanx in advance
<?define myPlattform = [PLATTFORM] ?>
Probably because myPlattform is a preprocessor variable and gets assigned before the PLATTFORM property ever has a value. If you want to conditionally install different components, you can try this way: How to use conditions in features in WiX?
This questions is possibly a duplicate of Is there a way to set a preprocessor variable to the value of a property?.
Update: If your goal is to set an installation location based on architecture, and your architecture is determined by the "PLATTFORM" property using the registry search you specified, then you could try the following:
<Property Id="PLATTFORM">
<RegistrySearch Id="myRegSearchPalttform"
Root="HKLM"
Key="SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Name="PROCESSOR_ARCHITECTURE"
Type="raw">
</RegistrySearch>
</Property>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SomeValue" />
</Directory>
</Directory>
<ComponentGroup Id="ProductComponentGroup">
<Component Id="ProductComponent" Guid="INSERT-GUID-HERE" Directory="INSTALLFOLDER">
<File Id="TestTextFile.txt" Source=".\TestTextFile.txt" KeyPath="yes"/>
</Component>
</ComponentGroup>
<Feature Id="ProductFeature" Level="1">
<ComponentGroupRef Id="ProductComponentGroup"/>
</Feature>
<SetDirectory Id="INSTALLFOLDER" Value="[ProgramFilesFolder]\SomeOtherValue">
PLATTFORM="AMD"
</SetDirectory>
Note: See that I used the SetDirectory element. I generally download the WiX weekly releases and never used that element until testing the above sample. Therefore I'm not sure what version SetDirectory was first introduced.

WebAppPool fails if AppPool already exists - WiX 3.5

This was working in WiX 3.0.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="inetpubDir" Name="inetpub">
<Directory Id="wwwrootDir" Name="wwwroot">
<Directory Id="INSTALLDIR" Name="DS3000Services" FileSource="\Server\Implementation\DS3000Services\Web">
<Component Id="DS3000ServicesVirtualDir" Guid="{4EFD7047-09F4-42e7-ACB5-A209D26B0338}">
<CreateFolder />
<iis:WebAppPool Id="AppPool" Name="[AppPoolName]" Identity="other" User="PortalUser" IdleTimeout="0" RecycleMinutes="0">
<iis:RecycleTime Value="1:00" />
</iis:WebAppPool>
<iis:WebVirtualDir Id="DS3000ServicesVirtualDir" Alias="[VIRTUALDIR]" Directory="INSTALLDIR" WebSite="DefaultWebSite">
<iis:WebApplication Id="DS3000ServicesApp" Name="DS3000 Services" Isolation="medium" WebAppPool="AppPool" />
</iis:WebVirtualDir>
</Component>
Install Log:
MSI (s) (10:E8) [09:57:58:553]: Invoking remote custom action. DLL: C:\Windows\Installer\MSI14A0.tmp, Entrypoint: WriteIIS7ConfigChanges
WriteIIS7ConfigChanges: Error 0x800700b7: Failed to add appPool element
WriteIIS7ConfigChanges: Error 0x800700b7: Failed to configure IIS appPool.
WriteIIS7ConfigChanges: Error 0x800700b7: WriteIIS7ConfigChanges Failed.
CustomAction WriteIIS7ConfigChanges returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (s) (10:4C) [09:57:58:585]: User policy value 'DisableRollback' is 0
MSI (s) (10:4C) [09:57:58:585]: Machine policy value 'DisableRollback' is 0
Action ended 9:57:58: InstallFinalize. Return value 3.
Installing on Win Server 2008 R2. The AppPool already exists. If I remove the AppPool, the installer succeeds. Any thoughts? Thanks...
I would recommend you to create a customAction for creating virtual directory along with Application Pool.
I have used custom action in my project for that purpose. In the custom action you can check whether the application pool with the given name exists or not.
Added inbuilt commands
<Component Id="VDWeb" Guid="493E3487-AA4C-4476-8CC0-4B1C763AF6F7" Permanent="no">
<iis:WebVirtualDir Id="VDir" Alias="[VDNAME]" Directory="dir_Application_0" WebSite="WebSelectedWebSite">
<iis:WebApplication Id="WebApp" Name="[VDNAME]" WebAppPool="ABCAppPool" />
</iis:WebVirtualDir>
<RegistryKey Root="HKLM" Action="createAndRemoveOnUninstall" Key="SOFTWARE\ABC\[ProductCode]\VirtualDirectory">
<RegistryValue Name="VDName" Type="string" Value="[VDNAME]"/>
</RegistryKey>
</Component>
<Component Id="AppPool_1" Guid="414a377f-e044-49d5-b905-66bf3da6489f" Permanent="no">
<util:User Id="PoolAccount" Domain="[DOMAINNAME]" Name="[LogonUser]" Password="[NT_PASSWORD]" CreateUser="no">
<util:GroupRef Id="IISUsersGroup"/>
</util:User>
<iis:WebAppPool Id="ABCAppPool_NT" Name="[APPPOOLNAME_NT]" ManagedRuntimeVersion="v4.0" ManagedPipelineMode="integrated" Identity="other" User="PoolAccount">
<iis:RecycleTime Value="05:00" />
</iis:WebAppPool>
</Component>
<util:Group Id="IISUsersGroup" Name="IIS_IUSRS"/>
<iis:WebSite Id="WebSelectedWebSite" Description="[WEB_WEBSITE_DESCRIPTION]">
<iis:WebAddress Id="AllUnassigned1" Port="[WEB_WEBSITE_PORT]" IP="[WEB_WEBSITE_IP]" Header="[WEB_WEBSITE_HEADER]" />
</iis:WebSite>
Am using this and it works perfectly fine.