How do I change url in .wxs file with build configuration - wix

I have a Wix install project in Visual Studio 2012 and have an xml node like
<MsiPackage ... DownloadUrl="http://uat.mywebsite.com/MyMSI.msi">
I want to change the url depending on the build configuration. i.e. in uat I want it to be http://uat.mywebsite.com/... and in release http://mywebsite.com/...
Is this possible, and if so how do I do it?

Your WiX project has access to build parameters, like the Configuration (debug or release). You can conditionally include the correct DownloadUrl for the current configuration by referencing $(var.Configuartion) in your component declarations:
Not tested this but something similar should work:
<?if $(var.Configuartion) = Release?>
<?define DownloadUrl = "http://uat.mywebsite.com/" ?>
<?elseif $(var.Configuartion) = Debug?>
<?define DownloadUrl = "http://mywebsite.com/" ?>
<?endif ?>
<MsiPackage ... DownloadUrl="$(var.DownloadURL)">

Related

WiX Change product name conditionally

I have a large .wxs file and a requirement to change the Product Name from MyApp Workstation version to MyApp Server version when the installer is launched on a Windows Server operating system. I read a lot and I found out that I need to relate to the following MSI property MsiNTProductType which returns the value 1 for workstation and 2 or 3 for server operating systems.
<?xml version="1.0" encoding="UTF-8"?>
<?define ProductName = "MyApp Workstation version" ?>
<Wix>
<Product Name="$(var.ProductName)" ... >
...
</Product>
</Wix>
If I use a condition like the following, it detects that I am on a workstation operating system (in my case Windows 10), but this is not what I want:
<Condition Message="This installer is for Windows Server only!">
<![CDATA[(MsiNTProductType > 1)]]>
</Condition>
I tried the preprocessor variable approach, but evidently it does not work:
<?if MsiNTProductType = 1 ?>
<?define ProductName = "MyApp Workstation version" ?>
<?else ?>
<?define ProductName = "MyApp Server version" ?>
<?endif ?>
I also tried SetProperty and CustomAction without any luck. I am stuck at this.
Is it possible to do something like this? What changes do I have to make to accomplish this? I am very new to WIX and I do not understand how it is supposed to work. Thank you.
LATER EDIT AND SOLUTION
After many days of trying tens of combinations, I was able to do this with the following code which I put before any CustomActions that were already defined:
<Property Id="ConditionalProductName" Value="MyApp Workstation version" />
<SetProperty Id="ConditionalProductName" Before="LaunchConditions" Value="MyApp Server version" >
<![CDATA[(MsiNTProductType > 1)]]>
</SetProperty>
<SetProperty Id ="ProductName" Before ="LaunchConditions" Value ="[ConditionalProductName]"/>
I hope this may help others too. Good luck.
The ProductName property can only be changed prior to the installation starting. Once MSI is running it's immutable.
The preprocessor statements you are trying effect build time not installation time.
The only way to do what you want is create a transform with the different name and then use a bootstrapper to install the MSI without a transform on a non server OS and install the MSI with a transform on a server OS.
Personally this isn't typical practice so I would push back on the requirement from the PM. The only reason I would go through the effort would be the business really really differentiated the branding on the marketing side. Otherwise this just isn't normally done.

WIX cannot find app.exe in x86/x64 output directory

I have a C# application which its build targets are x86 or x64. The build output is (for example) ProjectDir/bin/x86|x64/Debug|Release/*
In my *.wxs file I have defined thr following variable
<?define AppTargetPath = "$(var.MyApp.TargetPath)" ?>
Which points to ProjectDir/bin/Debug|Release/app.exe
If I build the installer, it fails because it does not find my app exe
<File Id="AppExe" Source="$(var.AppTargetPath)" KeyPath="yes"/>
If I look on Using Project References and Variables site (http://wixtoolset.org/documentation/manual/v3/votive/votive_project_references.html) I cannot find another variable.
Maybe try this:
Comment out your existing define.
Add the project building the EXE and your WiX project to the same solution.
Add a reference from the WiX project to the EXE / Binary project.
Try this markup (replace project name "TestConsoleApplication" with yours):
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component>
<File Source="$(var.TestConsoleApplication.TargetPath)" />
</Component>
</ComponentGroup>
</Fragment>
Rebuild All.
Toggle Release and Debug builds, then Rebuild All again.
Links:
Summary: My WiX Quick Start Tips.
Basic WiX Project: Step-by-step, Hello WiX project.
Real-World Sample: Real-World Example: WiX/MSI Application Installer
Actually I solved it by putting together the entire path on top of my wxs file:
<?define AppTargetFileName = "$(var.myApp.TargetFileName)" ?>
<?if $(var.Platform) = x64 ?>
<?define AppTargetPath = "$(var.myApp.ProjectDir)\bin\x64\$(var.myApp.Configuration)\$(var.AppTargetFileName)" ?>
<?elseif $(var.Platform) = x86 ?>
<?define AppTargetPath = "$(var.myApp.ProjectDir)\bin\x86\$(var.myApp.Configuration)\$(var.AppTargetFileName)" ?>
<?else ?>
<?define AppTargetPath = "$(var.myApp.TargetPath)" ?>
<?endif ?>

How can I use an update condition to set variables in Wix?

We are using Wix V3.11 to build an msi setup for our C#-Application. We have a 32 Bit and an 64 Bit build for each version:
The preallocated installation path for the 32 Bit build is: 'C:\Program Files (x86)'.
The preallocated installation path for the 64 Bit setup is: 'C:\Program Files'.
We use the following declaration to set the paths:
<?define bitness = $(var.Platform) ?>
<?if $(var.Platform) = "x86" ?>
<?define ProgramFilesPath = ProgramFilesFolder?>
<?define Win64 = no?>
<?else?>
<?define ProgramFilesPath = ProgramFiles64Folder?>
<?define Win64 = yes?>
<?endif?>
Using the variable here:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.ProgramFilesPath)" Name="$(var.ProgramFilesPath)">
[... more folder ...]
</Directory>
</Directory>
The Problem: When the consumer changes the path for the first installation to e.g. 'C:/MyFolder' and executes an updade, then the msi setup moves the software to 'C:\Program Files (x86)' or 'C:\Program Files'.
Question: How can I keep the custom installation path 'C:/MyFolder' of the first installation on an update? Perhaps is there any 'update' condition I can use? My imagination:
<?define bitness = $(var.Platform) ?>
<?if UPDATE ?> <!-- here -->
<?if $(var.Platform) = "x86" ?>
<?define ProgramFilesPath = ProgramFilesFolder?>
<?define Win64 = no?>
<?else?>
<?define ProgramFilesPath = ProgramFiles64Folder?>
<?define Win64 = yes?>
<?endif?>
<?endif?>
Let's assume that by "update" you mean a major upgrade because it would be extremely strange if a patch or minor update moved all the files from one location to another.
If you are using the usual WiX property name, then the directory chosen by the user will be INSTALLFOLDER, although it's not clear if you are using that or TARGETDIR. Basically you can store the user's final choice in a registry item (or use the WiX "remember property" pattern). On a major upgrade you can retrieve that property and set your INSTALLFOLDER value to that directory on condition that WIX_UPGRADE_DETECTED is set (the default property id used in the major upgrade element). Presumably you will also suppress the browse dialog that allows the user to choose the folder.
Having said that:
It's not clear why you don't want the user to install the major upgrade to a new location if they want to, if the app continues to work.
Those default folders aren't really preallocated - they are just the standard defaults. They are the recommended locations so it might be better to disallow changing them because of the opportunities for unexpected behavior. For example, attempting to install the 32-bit MSI to the native program files folder on an x64 system will result in redirection to the program files (x86) location, which may surprise the user.

Wix Toolset - Variable Shared Across Projects/Solution

I am trying to share a variable across 2 of my wix projects but I am having issues.
Basically I am trying to accomplish having the version number of my bootstrapper and MSI in one file and then this referenced by the two projects.
I have three projects
Install - This is a setup project that creates an .msi file
Bootstrapper - This is a Wix Bootstrapper project that references and runs the .msi file at runtime
Shared - This is a wixlib project that contains a single variable in a fragment that is the version number
The shared project contains a single file i have called GlobalVars.wxs and looks like this
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<?define VersionNo = "6.86.123"?>
</Fragment>
</Wix>
The bootstrapper references this variable like this
<Bundle Name="ProgramName" Version="$(var.VersionNo)" Manufacturer="CompanyName" UpgradeCode="Guid" Compressed="no">
and the Install project references the variable like this - and has a reference to the .wxs from the shared project
<Product Id="*" Name="Program Name" Language="2057" Version="$(var.VersionNo)" Manufacturer="CompanyName" UpgradeCode="guid">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated"/>
<?include GlobalVars.wxs ?>
Both projects have references setup to the wixlib project that contains the variable
When i attempt to build I am getting this error on both the install and bootstrapper project
Undefined preprocessor variable '$(var.VersionNo)'.
If the <?include?> tag resolved the issue I would expect the install project to build
Does anyone have any ideas as to what I might be doing wrong here?
To me it looks like the variable has not been defined by the time the build attempts to call it, but I am unsure as to show to change the order to ensure the variable is defined before anything else
Thanks for the help
I believe the answer to this question will help. I've used it and noticed that properties seem to be usable in my main wxs file.
To summarise, you need to set up a fake componentGroup in your library fragment, and use it in your installer. You do not need the include anymore, as long as the fake componentGroup from your fragment is referenced as a componentGroupRef in your main install, and your wixlib project is referenced in your installer project through VS (you said you'd already done this in your comments above).
Your library fragment might look something like this.
<Fragment id="fragment_id_may_not_be_needed">
<?define VersionNo = "6.86.123"?>
<ComponentGroup Id="c.define_version_num" />
</Fragment>
If the define for whatever reason doesn't work, try using a property instead. I'd be interested to know which works. Properties seem to work for me.
Then reference it in your main install like this:
<Feature Id="Main_installation" Title="Main installation" Level="1">
<!-- bringing in fragments from the shared libraries -->
<ComponentGroupRef Id="c.define_version_num" />
</feature>
Give it a whirl.

Wix Include file (.wxi) throws exception

I am a beginner in Wix and we are trying to migrate from Installshield to Wix. However I am stuck with an error which I am unable to resolve. I have done my share of research online before posting this message and I am hoping to get some help from you experts in case someone had a similar problem and would be kind enough to point out the silly mistake I am making here.
Here is my Wix include file: properties.wxi
<Include>
<?define Language="1033"?>
<?define Manufacturer="ABC Inc"?>
<?define Name="TRIAL-MSI"?>
<?define UpgradeCode="....GUID...."?>
<?define Version="09.00.0021"?>
<?define Comments="Contact: team#abc.com"?>
<?define Description="TRIAL Application"?>
</Include>
And I am calling it in my code as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include properties.wxi ?>
<Product Id="*"
Name="${var.Name}"
Language="${var.Language}"
Manufacturer="${var.Manufacturer}"
UpgradeCode="${var.UpgradeCode}"
Version="${var.Version}" >
<Package Comments="${var.Contact}"
Description="${var.Description}"
InstallerVersion="200"
Keywords="Installer,MSI,Database"
Languages="${var.Language}"
Manufacturer="${var.Manufacturer}"
Compressed="yes"
Platform="x86" />
I am compiling my script on the command line:
candle -arch x86 -I properties.wxi trial.wxs
I keep getting errors as follows:
error CNDL0048 : The document element name 'Include' is invalid. A Windows Installer XML source file must use 'Wix' as the document element name.Source trace:
And I guess because Candle did not accept the include file, it throws exception for:
error CNDL0008 : The Product/#Language attribute's value, '${var.Language}', is not a legal integer value.
Could someone please help me with this? Any help is greatly appreciated.
I had this error when migrating wxs files to wxi
Setting the files Build Action property in Visual studio from Compile to Content fixed it.
The -I flag to candle is used to specify a directory to search for include files:
usage: candle.exe [-?] [-nologo] [-out outputFile] sourceFile
[sourceFile ...] [#responseFile]
-I add to include search path
The Wix preprocessor will automatically look in the directory of the current source file for include files so there is no reason to specify the include file on the command line. Your command line should only include the Wix source files:
candle -arch x86 trial.wxs
UPDATE:
Wix variables are inserted using $(var.VARIABLENAME). You have all of your variables surrounded with curly braces instead of parentheses.