I have the following code in my Product.wxs file
<Wix>
<?define ProductVersion="!(bind.fileVersion._957E198E_2074_A3FA_A554_6FE5D8E9F4FD)" ?>
<?define MajorVersion="!(bind.property.ProductVersion.Major)" ?>
<Product Id='*' Name='Software v$(var.MajorVersion)' Version='$(var.ProductVersion)' Manufacturer='...' UpgradeCode='...' Codepage='...'>
[...]
</Product>
</Wix>
The above is based on this Binding WIX FileVersion sub values? question's answer.
It gives me the following error though
My Plan B was smth like
<?define MajorVersion="!(bind.fileVersion._957E198E_2074_A3FA_A554_6FE5D8E9F4FD.Major)" ?>
or
<?define MajorVersion="!(bind.fileVersion.major._957E198E_2074_A3FA_A554_6FE5D8E9F4FD)" ?>
but those don't work either.
Ultimately I want to use the MajorVersion property/variable to be part of the install directory.
<CustomAction Id='DIRCA_TARGETDIR' Property='TARGETDIR' Value='[ProgramFilesFolder][Manufacturer]\[MajorVersion]\[ProductName]' Execute='firstSequence' />
Any help is greatly appreciated.
After some more digging I eventually found an answer myself.
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<?define MainAssemblyVersion="!(bind.fileVersion._957E198E_2074_A3FA_A554_6FE5D8E9F4FD)" ?>
<?define MajorVersion="!(bind.property.ProductVersion.Major)" ?>
<Product Id='*' Name='Software v$(var.MajorVersion' Language='1033' Version='$(var.MainAssemblyVersion)' Manufacturer='...' UpgradeCode='...' Codepage='...'>
[...]
<!-- Initialize the 'TARGETDIR' directory property. -->
<CustomAction Id='DIRCA_TARGETDIR' Property='TARGETDIR' Value='[ProgramFilesFolder][Manufacturer]\[ProductName] v$(var.MajorVersion)' Execute='firstSequence' />
[...]
</Product>
</Wix>
I believe I was partly confused by the fact that bind.property.ProductVersion already exists and doesn't have to be declared (which I did in my first example)
Once you have the major version part in a variable, using it $(var.MainAssemblyVersion) is really all it needs.
Related
I am trying to create a Wix Bootstrap executable that contains an .msp patch file. I have generated the patch file using pyro.exe and the patch itself works absolutely fine and updates the required files correctly when ran by itself.
However we package all our .msi's in a Wix Bootstrap project with a custom user interface, which I have cloned for the patch files. However when running the executable this way it removes all the files from the install directory.
Has anyone experienced this issue before or am I doing something wrong? Thank you in advance, let me know if you need further code examples.
BootstrapBundle.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:vi="http://schemas.visualinstaller.de/VisualInstallerWixExtension">
<Bundle Name="MyProgram" Version="1.0.0.1"
Manufacturer="Test"
UpgradeCode="GUID"
SplashScreenSourceFile="Resources\splash.bmp"
IconSourceFile="Resources\icon.ico">
<Update Location="http://test.laika42.com/UpdateInfo.xml"/>
<BootstrapperApplicationRef Id='ManagedBootstrapperApplicationHost'>
<PayloadGroupRef Id='VisualInstallerRuntimeFiles'/>
</BootstrapperApplicationRef>
<Variable Name="INSTALLFOLDER" bal:Overridable='yes'
Value='[ProgramFilesFolder]Test\MyProgram\'/>
<Chain>
<PackageGroupRef Id='NetFx45Web' /> <!-- Fails to build without this? -->
<MspPackage Id='PatchMsp' SourceFile='C:\Patches\Patch.msp' />
</Chain>
</Bundle>
</Wix>
Just had this problem myself. It seems that the UpgradeCode for the bundle must be different to the UpgradeCode for the MSI - the bundle will remove anything older with the same Bundle UpgradeCode, including the original full MSI. I have to say I find the Wix documentation less than illuminating. Bdum-tsh.
The important bits seem to be having different UpgradeCodes for the MSI, the MSI bootstrapper bundle and the patch bootstrapper bundle but keeping each one of the three the same going forward, and the RelatedBundle element.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<?include $(var.SolutionDir)\Installer\ProductDefs.wxi?>
<?include $(var.SolutionDir)\Installer\version.wxi?>
<!-- A DIFFERENT UpgradeCode to the main bundle, but consistent for all patches. I think. -->
<?define PatchBundleUpgradeCode = "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"?>
<!-- The UpgradeCode of the Bundle that was used to deploy the MSI originally. -->
<?define MSIBundleUpgradeCode = "BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB"?>
<!-- ... both of which are different to the MSI UpgradeCode. -->
<Bundle Name="$(var.ProductName) $(var.ProductVersion)"
ParentName="$(var.ProductName)"
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="$(var.PatchBundleUpgradeCode)"
IconSourceFile="$(var.SolutionDir)\Installer\MyIcon.ico"
AboutUrl="https://www.somecompany.com/"
HelpUrl="https://www.somecompany.com/support/"
>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication
LicenseFile="$(var.SolutionDir)\Bootstrapper\license.rtf"
LogoFile="$(var.SolutionDir)\Bootstrapper\Logo.jpg"
ShowVersion="yes"
SuppressOptionsUI="yes"
/>
</BootstrapperApplicationRef>
<OptionalUpdateRegistration Classification="Update" Name="$(var.ProductName) $(var.ProductVersion)"/>
<RelatedBundle Id="$(var.MSIBundleUpgradeCode)" Action="Patch" />
<Chain>
<MspPackage SourceFile="$(var.ProjectDir)\Release\$(var.ProductName) $(var.ProductVersion) Patch.msp" DisplayInternalUI="yes"/>
</Chain>
</Bundle>
</Wix>
Also, if you want to apply more than one minor patch, make sure your PatchMetadata element (in the patch.wxs, not the bundle.wxs) contains the following attribute otherwise the first patch will apply but subsequent ones won't.
MinorUpdateTargetRTM="1"
I'm using Wix 3.11 and trying to set the install privileges of my package conditionally.
What I'm trying to do is:
<?if Privileged = 0 ?>
<Package InstallerVersion="405" Compressed="yes" InstallScope="perUser" InstallPrivileges="limited" />
<?else ?>
<Package InstallerVersion="405" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated" />
<?endif ?>
However this doesn't work. When installing, the one with elevated privileges is always picked.
Also, I've tried to create a variable in a .wxi file and set it like this:
.wxi file:
<?if Privileged = 0 ?>
<?define myScope = "perUser" ?>
<?define myPrivileges = "limited" ?>
<?else?>
<?define myScope = "perMachine" ?>
<?define myPrivileges = "elevated" ?>
<?endif?>
.wxs file:
<Package InstallerVersion="405" Compressed="yes" InstallScope="$(var.myScope)" InstallPrivileges="$(var.myPrivileges)" />
But the same happens again: elevated privileges are always picked.
I did my tests on 2 different machines, with non-admin users.
I did not find any solution on the internet so I'm wondering: is it possible to set up a package conditionally?
Thanks for your time.
EDIT:
I have found the AdminUser property, which seems to be exactly what I need.
I changed my wxs file accordingly to have AdminUser set:
<Package InstallerVersion="500" Compressed="yes" />
<SetProperty Id="MSIUSEREALADMINDETECTION" Value="1" Sequence="first"/>
<SetProperty Id="ALLUSERS" Value="2" Sequence="first"/>
<SetProperty Id="MSIINSTALLPERUSER" Value="1" Sequence="first"> <![CDATA[NOT AdminUser]]> </SetProperty>
When reading the log file of the installation, I noticed AdminUser was set before MSIUSEREALADMINDETECTION, and setting MSIUSEREALADMINDETECTION wouldn't trigger a reset for AdminUser.
I scheduled my SetProperties to the most prior action I could find, which was "FindRelatedProducts", however AdminUser is set even before that (actually before both installExecuteSequence and installUISequence), I was unable to get MSIUSEREALADMINDETECTION set first.
I believe there is no way to determine wether you are running your installation under an admin or a standard session.
If anyone know a solution, please feel free to advise.
Thank you Michael and Brian for your time.
I'm using WiX to build an installation package for a product at my company and I want to be able to build two slightly different versions of the .msi depending on if it is meant to be used internally in the company for testing or externally for customers.
The internal version should be built with no UpgradeCode, so that we can have several versions installed at the same time for comparison. The external version should have a static UpgradeCode.
WiX does not allow me to have UpgradeCode auto generated by doing this:
<?if $(var.Configuration) = "Internal Release"?>
<?define UpgradeCode = "*"?>
<?else?>
<?define UpgradeCode = "[REALGUID]"?>
<?endif?>
<Product ... UpgradeCode="$(var.UpgradeCode)">
To have the UpgradeCode "auto generated" you have to completely ommit the UpgradeCode attribute.
Anyone have any suggestions on how to accomplish this?
Probably you can't use * for Upgrade Code (i'm not sure) but you could pass it as property through msbuild which i do for ProductCode conditionaly (if we are building patches or not)
<UpgradeCode Condition="$(InternalRelease)==1">{$([System.Guid]::NewGuid().ToString().ToUpper())}</UpgradeCode>
In your msbuild.proj add that property in your Target/msbuild project/Properties.
Add UpgradeCode=$(UpgradeCode) in you constants (wixproj)
Then in your main wxs add something like this:
<?if $(var.UpgradeCode)=""?>
<?define UpgradeCode=your-static-upgradecode ?>
<?endif?>
So if the project receives the upgrade code then it will use that one otherwise will be your fixed upgrade code in defined.
And finally to generated the guid call the msbuild.proj with /p:InteralRelease=1
Adding this answer as an alternative solution for other users with the same challenge.
Altough IlirB's answer probably would work as expected (I haven't tried it as I solved the problem with my own solution before the answer was provided), I solved the problem by conditionally including one of 2 different versions of the Product-tag. Of which only one had the UpgradeCode defined.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Config.wxi?>
<?if $(var.IsExternalRelease) = yes?>
<Product Id="$(var.ProductID)" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package Id="$(var.PackageID)" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<PropertyRef Id="AllProperties"/>
<UIRef Id="CUSTOM_UI"/>
<FeatureRef Id="F_AllFeatures"/>
</Product>
<?else?>
<Product Id="$(var.ProductID)" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)">
<Package Id="$(var.PackageID)" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MediaTemplate EmbedCab="yes"/>
<PropertyRef Id="AllProperties"/>
<UIRef Id="CUSTOM_UI"/>
<FeatureRef Id="F_AllFeatures"/>
</Product>
<?endif?>
</Wix>
Because I made an effort in splitting the wix code into several pieces and referring them from the Product tag, there was not much duplication of code.
Hi I have a C/C++ Header file with my products version info init as follows:
#define nMajorVersion 4
#define nMinorVersion 4
#define nPointVersion 8
#define nBuildVersion 33
#define s_szFileVersion "4.4.8.33"
#define s_szProductVersion "4.4.8.33"
Is there any way I can automatically read from this file to update my version number in my wix 3.6 installer? At the moment I have it hard coded and this is not ideal for when it is released. Thanks
What you can do is create a c/c++ program which generates a file Version.wxi which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define ProductVersion.Major="4"?>
<?define ProductVersion.Minor="4"?>
<?define ProductVersion.Revision="8"?>
<?define ProductVersion.Build="33"?>
<?define ProductVersion="4.4.8.33"?>
....
</Include>
Then you can include and use those version numbers in the main wxs file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Version.wxi ?>
<?define UpgradeCode="GUID"?>
<Product Id="*"
Name="$(var.ProductName) $(var.ProductVersion.Major).$(var.ProductVersion.Minor)"
Version="$(var.ProductVersion)" Language="1033"
Manufacturer="$(var.Company)" UpgradeCode="$(var.UpgradeCode)">
Generate the Version.wxi just before you compile your wix project. For example modify the .wixproj file to add a target which does that.
I already know about the UserLanguageID and SystemLanguageID properties, but is there any way I could put this number into the language attribute of the Product tag?
I'm probably either doing something very wrong, or it can't be done.
Thanks
UserLanguageID and SystemLanguageID are runtime properties, ie they don't exist until the MSI actually runs. The product's language code, on the other hand, is determined when the MSI is generated by the Wix toolset. AFAIK there's no way to change it dynamically.
Short answer: it can't be done.
You're not very clear about what it is you're trying to do... however I use something like the following. Don't know if this will help?
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" Codepage="1252" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="Language">en-US</String>
<!-- .... -->
</WixLocalization>
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
UpgradeCode="$(var.Property_UpgradeCode)"
Name="!(loc.ApplicationName)"
Language="!(loc.Property_ProductLanguage)"
Version="$(var.version)"
Manufacturer="!(loc.ManufacturerName)" >
<!-- .... -->
</Product>
</Wix>