Unresolved reference in WiX - wix

I need to check for .NET Framework before installing. I've added this
<PropertyRef Id="NETFRAMEWORK40" />
<Condition Message="This application requires .NET Framework 4.0. Please install the .NET Framework then run this installer again. Contact support at support#Swiftposter.com if you have further issues.">
<![CDATA[Installed OR NETFRAMEWORK40]]>
</Condition>
The start of the file contains
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
and on linking I get the error
error LGHT0094 : Unresolved reference to symbol
'Property:NETFRAMEWORK40' in section 'Product:*'.
Is there a specific place where I should insert these lines? I tried most places I can think of.

You should add reference to WixNetfxExtension.
Use the property NETFRAMEWORK40FULL instead.

Related

Can I move common install conditions to a shared WiX Installer project

I have multiple WiX installer projects in my solution. And all of the installers in the main wxs file under the Product element have the same list of launch conditions, such as privileges, OS version on the target machine, whether NET48 framework is installed or not, etc.
<Condition Message="You need to be an administrator to install this product.">
Privileged
</Condition>
<Condition Message='This product is designed to be installed on Windows 7 or higher Windows Operating System'>
<![CDATA[VersionNT64 >= 601]]>
</Condition>
<PropertyRef Id='WIXNETFX4RELEASEINSTALLED'/>
<Condition Message='This setup requires the .NET Framework 4.8 to be installed.'>
<![CDATA[Installed OR (WIXNETFX4RELEASEINSTALLED >= "#528040")]]>
</Condition>
So I was wondering if it is possible to have these conditions moved into a shared common project in my solution that I can refer to that project from all my installer projects and inject the conditions from that shared place?
If you are only sharing those Launch Conditions then consider using an include file. The conditions will be compiled separately for each project, rather than once, but then you can include them easily without needing to create a shared wixlib.
<?xml version="1.0" encoding="UTF-8"?>
<!-- LaunchConditions.wxi -->
<Include>
<Condition Message="You need to be an administrator to install this product.">
Privileged
</Condition>
<Condition Message='This product is designed to be installed on Windows 7 or higher Windows Operating System'>
<![CDATA[VersionNT64 >= 601]]>
</Condition>
<PropertyRef Id='WIXNETFX4RELEASEINSTALLED'/>
<Condition Message='This setup requires the .NET Framework 4.8 to be installed.'>
<![CDATA[Installed OR (WIXNETFX4RELEASEINSTALLED >= "#528040")]]>
</Condition>
</Include>
then in each project include it with
<?include LaunchConditions.wxi?>
WiX doesn't have a ConditionRef element. It's a shame cause it probably should. However fragements are consumed atomically so if you put them in with something else like a Property you could ref the property and get it all together.
I don't know how clean you want your Condition table but another concept is just put all your conditions in one fragement and share them with all your projects. Then for each condition you an enabling property. This way the condition only evaluates if the property is set.
Here's something I wrote 16 years ago.... I'd be happy to assist if you want to do something like this.
http://blog.iswix.com/2006/07/short-comings-of-launchconditions.html

How to check for .net framework 4.7.1 with Wix 3.11

I am trying to check for .net Version with Wix 3.11 via Condition. This works fine until 4.5 like this:
<PropertyRef Id="NETFRAMEWORK45" />
<Condition Message="This application requires .NET Framework 4.5. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK45]]>
</Condition>
Checking for anything above 4.5 seems not to be possible - at least not with this mechanism. How can I do that?
That method (PropertyRef) is syntactical sugar. The NetFxExtension preprocessor injects the implementation at compile time. WiX is currently lagging behind. The implementation you are looking for would be something like:
<PropertyRef Id="NETFRAMEWORK45" />
<Condition Message="This application requires .NET Framework 4.7.1. Please install the .NET Framework then run this installer again."><![CDATA[Installed OR NETFRAMEWORK45>=#461308]]>
</Condition>
https://github.com/wixtoolset/issues/issues/5575
Update (hot33331): Added a # before the number 461308. Without that it did not work for me.

"MsiNTProductType", "POWERSHELLVERSION" in WIX 3.6

In my WIX project, I want to use Cited Properties.
The following Cited Properties work well
<PropertyRef Id="NETFRAMEWORK45"/>
<Condition Message="You must install .Net Framework 4.5">
<![CDATA[Installed OR NETFRAMEWORK45]]>
</Condition>
<PropertyRef Id="VersionNT64"/>
<Condition Message="This application cannot be running on 32 bit architechure">
<![CDATA[Installed OR VersionNT64]]>
</Condition>
But other Properties use my debug to filed with the following message:
"Error 1 Unresolved reference to symbol 'Property:MsiNTProductType' in section 'Product:*'"
for example:
BTW, the WixNetFxExtension exist.
MsiNTProductType is a valid built-in Windows Installer property, so this should work OK provided you haven't got any typos in the WIX code. As Phil asks, please update your question with the actual Wix code that references the MsiNTProductType property.
In my experience it is easy to mix up something trivial in a Wix source file, and the error is most likely just an extra comma, dot or some other trivial typo. I'll just include a link to the MSI Property Reference.
This is my properties section.
The only one that work is "NETFRAMEWORK45".
The rest of them in comment because they cuse the error I mention.
I must understand why the error occured.
Thanks,
Didi
<PropertyRef Id="NETFRAMEWORK45"/>
<Condition Message="You must install .Net Framework 4.5">
<![CDATA[Installed OR NETFRAMEWORK45]]>
</Condition>
<!--
<PropertyRef Id="POWERSHELLVERSION"/>
<Condition Message="You must install Powershell ver 3.0">
<![CDATA[Installed OR POWERSHELLVERSION >= "3.0"]]>
</Condition>
<PropertyRef Id="VersionNT64"/>
<Condition Message="This application cannot be running on 32 bit architechure">
<![CDATA[Installed OR VersionNT64]]>
</Condition>
<PropertyRef Id ="VersionNT"/>
<Condition Message="Operating system must be Windows Server 2008 or higher">
<![CDATA[VersionNT >= 600]]>
</Condition>
<PropertyRef Id ="MsiNTProductType"/>
<Condition Message="Operating system must be SERVER O.S">
<![CDATA[MsiNTProductType <> 3]]>
</Condition>
-->
MsiNTProductType is a standard Windows Installer property - you're trying to redefine it and getting that error. All you need for the standard properties is the condition - delete the PropertyRef for MsiNTProductType, VersionNT, VersionNT64.

WiX bootstrapper disable .NET Framework installation chaining

In my WiX installer, I do not want .NET installed automatically if it isn't installed. It should just give a warning or merely error out.
The reason to avoid it is explained here:
One HUGE word of
caution here: Because the .Net installer will technically be part of
your install chain, if the user installs .Net but then cancels your
install, your installer will still be listed in the Add/Remove
programs since one if it’s components (the .Net installer) completed.
Tread with caution.
He seems to be intentionally including it. But I'm not and I happened to set <supportedRuntime version="v4.5" /> which I guess isn't a real version (4.5 => 4.0 as far as this is concerned?). My WiX managed bootstrapper application exe automatically prompted me to download and install the "missing" .NET Framework.
For computers that ARE missing 4.0, I don't want this to happen. WiX also complains if I leave out:
<WixVariable Id="WixMbaPrereqLicenseUrl" Value="..." />
<WixVariable Id="WixMbaPrereqPackageId" Value="..." />
in which I literally leave in ... because I don't want it to work anyway.
In this thread, #Shruthi asks
Is there a way to replace the prerequisite .Net install UI with just an notification to the user that they need to install a particular version of .Net before they can install the bundle?
And Rob Mensching replies:
Yes, that is possible now.
... BUT HE DOESN'T ELABORATE. How is it possible now?
Thanks!
===============
In my Bundle's Bootstrap.Config:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v6" /> <!-- Pretending it's the future! -->
</startup>
The Bundle itself does not reference any .NET stuff and does not reference WixNetFxExtension and uses the custom <BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost" />
To answer how to handle checking for the .Net 4.0 Framework include the WixNetfxExtension in your project
then under product add a reference to the property NETFRAMEWORK40FULL and put a condition on it.
<PropertyRef Id="NETFRAMEWORK40FULL"/>
<Condition Message="This application requires .NET Framework 4.0. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK40FULL]]>
</Condition>
for the chained case again include wixnetfxextension and include NetFx40Redist package group
<PackageGroupRef Id="NetFx40Redist"/>

RemotePayload: The system cannot find the file '' with type ''

Moving to WiX 3.6, I'm trying to make use of burn features to ease potential download/install of required pieces, such as a specific VC++ runtime.
I started small with just some "test.wxs", see below, which is OK for candle.exe:
$ candle test.wxs
Windows Installer Xml Compiler version 3.6.3303.0
Copyright (C) Outercurve Foundation. All rights reserved.
test.wxs
But light.exe chokes on it:
$ light test.wixobj -ext WixBalExtension
Windows Installer Xml Linker version 3.6.3303.0
Copyright (C) Outercurve Foundation. All rights reserved.
light.exe : error LGHT0103 : The system cannot find the file '' with type ''.
Could someone help with this (rather cryptic) error message?
It seems related to RemotePayload, since a modified version with local file works correctly. However, I'd like to save on package size and leave the downloading on the target machine if so needed.
Full content of "test.wxs" was:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle Version="1.0.0.0"
UpgradeCode="e349236d-6638-48c5-8d8b-db47682b9aeb">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<!-- C++ Runtime -->
<ExePackage Name="vcredist_x64.exe"
DownloadUrl="http://www.microsoft.com/en-us/download/confirmation.aspx?id=2092" >
<RemotePayload CertificatePublicKey="F321408E7C51F8544B98E517D76A8334052E26E8"
CertificateThumbprint="D57FAC60F1A8D34877AEB350E83F46F6EFC9E5F1"
Description="Microsoft Visual C++ 2008 Redistributable Setup"
Hash="13674C43652B941DAFD2049989AFCE63CB7C517B"
ProductName="Microsoft Visual C++ 2008 Redistributable"
Size="4961800"
Version="9.0.30729.17" />
</ExePackage>
</Chain>
</Bundle>
</Wix>
Partial answer to my own question:
The error message disappears if I add the attribute Compressed="no" to the ExePackage element.
Documentation about "Compressed" attribute says: "Whether the package payload should be embedded in a container or left as an external payload" and its value can be "yes", "no", or "default".
Using "yes" or "default" triggers the error message. Using "no" doesn't.
I had the same trouble with another package (the .NET framework) and Wix 3.7. I used the Wix source code to find the appropriate package names and registry keys to test, and then pasted the relevant bits into my installer. Then, I intentionally set 'Compressed="yes"' because I wanted to embed the file in my installer instead of having it downloaded.
There was a report similar to yours posted in this mailing list thread:
Benjamin Mayrargue: If an ExePackage has a DownloadUrl and Compressed is set to yes, light failed with error LGHT0103: The system cannot find the file '' with type ''.
Markus Wehrle: Ok, I see. If you want to have the ExePackage compressed into your bootstrapper.exe (compressed="yes") you need to specify it using "Source" attribute. Cause it will be compressed into your boostrapper during compile time, you must not declare a DownloadUrl. If you specifiy compressed="no" your ExePackage gets downloaded from the DownloadUrl during the installation of your boostrapper.
Rob Mensching: More specifically, you cannot use RemotePayload element and Compressed='yes' on the ExePackage element together. That doesn't make sense and the bug here is that the compiler didn't give you an error message here saying that.
So yes, you've correctly identified the same fix to the problem.
The Compressed attribute, by the way, specifies 'Whether the package payload should be embedded in a container or left as an external payload.' That external payload can either be a RemotePayload or another file on the disk, but the typical setup is a single bootloader with all the resources embedded into it.
Using yes for the Compression attribute will allow your application and the VC++ runtime to be installed even if the user has a slow or nonexistent Internet connection. Remove the DownloadUrl and RemotePayload from your installer, and replace them with just Compressed="yes" like this:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle Version="1.0.0.0"
UpgradeCode="e349236d-6638-48c5-8d8b-db47682b9aeb">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<!-- C++ Runtime -->
<ExePackage Name="vcredist_x64.exe"
Compressed="yes">
</ExePackage>
</Chain>
</Bundle>
</Wix>
Then download the vcredist_x64.exe file (yourself, once) and place it adjacent to your test.wxs file. Adjust 'Name' if you want it in a different location. Note that this will increase the size of your resulting bootstrapper by about the size of vcredist_x64.exe, so it's not a good idea if your users will be downloading your installer.
In my case the error was thrown because the filename/directory path was over 255 characters. The file exist yet the compiler is stating that the file doesn't exist.