Including .NET installer in WiX Bundle not detecting if already installed

7

I'm on WiX 3.7, and I can't get the simple <PackageGroupRef Id="NetFx40Web"/> bundle element to work, as it doesn't bring across the Net FX installer package, or embed it in the setup.exe. I've resorted to creating my own package for this in my Bundle.wxs file, but I am still having trouble. It seems to always try to install .NET 4, even if the machine already has .NET installed.

I'm not quite sure of the difference between InstallCondition and DetectCondition. I think InstallCondition is used to install the package if the evaluation is true, otherwise uninstall it. How does this work with things that are typically permanent=yes, such as most pre-requisites? DetectCondition is almost the opposite, I think, in that it checks if it's already on the system, and if so, doesn't install it.

Below is my full Bundle.wxs file which is in a Visual Studio WiX Bootstrapper project. I'm attempting to look at the registry and scope out of .NET 4.0 registry key is there. If it is present, then I don't want to install .NET 4., and if it's not there, then install it. But, this isn't working, and it always attempts to install .NET.

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Bundle
        Name="MyProgramBootstrapper"
        Version="1.0.0.0"
        Manufacturer="Microsoft"
        UpgradeCode="{2299B51D-9FD8-4278-90C8-2B79DB37F402}">

        <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
        <Chain>
          <PackageGroupRef Id="Netfx4Full"/>
          <MsiPackage
              Id="MyProgramInstaller"
              SourceFile="$(var.MyProgramInstaller.TargetPath)"
              Compressed="no"/>
        </Chain>
    </Bundle>

    <Fragment>
        <Property Id="NET40_FULL_INSTALL_32">
            <RegistrySearch
                Id ="SearchNet40_32bit"
                Root="HKLM"
                Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
                Name="Version"
                Type ="raw"/>
        </Property>
        <Property
            Id="NET40_FULL_INSTALL_64">

            <RegistrySearch
                Id ="SearchNet40_64bit"
                Root="HKLM"
                Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full"
                Name="Version"
                Type ="raw"
                Win64="yes" />
        </Property>

        <WixVariable
            Id="WixMbaPrereqPackageId"
            Value="Netfx4Full" />
        <WixVariable
            Id="WixMbaPrereqLicenseUrl"
            Value="NetfxLicense.rtf" />
        <PackageGroup
            Id="Netfx4Full">
          <ExePackage
              Id="Netfx4Full"
              Cache="no"
              Compressed="no"
              PerMachine="yes"
              Permanent="yes"
              Vital="yes"
              SourceFile="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\dotNetFx40_Full_x86_x64.exe"
              DetectCondition="NET40_FULL_INSTALL_32 OR NET40_FULL_INSTALL_64"
              DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/>
        </PackageGroup>
    </Fragment>
</Wix>

Bootstrapper installer log:

[010C:2FB0][2013-05-10T12:07:07]w120: Detected partially cached package: Netfx4Full, invalid payload: Netfx4Full, reason: 0x80070570
[010C:2FB0][2013-05-10T12:07:07]i052: Condition 'NETFRAMEWORK40' evaluates to false.
[010C:2FB0][2013-05-10T12:07:07]w120: Detected partially cached package: MyInstaller, invalid payload: f4832BA0972BDE9B6FA8A19FBB614A7BA, reason: 0x80070570
[010C:2FB0][2013-05-10T12:07:07]i101: Detected package: Netfx4Full, state: Absent, cached: Partial

Update, with solution. I used the built-in WiX RegistrySearch to determine if it's installed. I had to reference the WixUtilExtension.dll in my Bundle project. Here's the updated Bundle.wxs:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
    xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
    xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
>
    <Bundle
        Name="MyProgramBootstrapper"
        Version="1.0.0.0"
        Manufacturer="Microsoft"
        UpgradeCode="{2299B51D-9FD8-4278-90C8-2B79DB37F402}">

        <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
        <Chain>
            <PackageGroupRef Id="Netfx4Full"/>
            <!-- TODO: Define the list of chained packages. -->
                  <!-- <MsiPackage SourceFile="path\to\your.msi" /> -->
            <MsiPackage
                Id="MyProgramInstaller"
                SourceFile="$(var.MyProgramInstaller.TargetPath)"
                Compressed="no"  />
        </Chain>
    </Bundle>

    <Fragment>
        <util:RegistrySearchRef Id="NETFRAMEWORK40"/>
        <PackageGroup
            Id="Netfx4Full">

            <ExePackage
                Id="Netfx4FullExe"
                Cache="no"
                Compressed="no"
                PerMachine="yes"
                Permanent="yes"
                Vital="yes"
                SourceFile="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\DotNetFX40\dotNetFx40_Full_x86_x64.exe"
                InstallCommand="/q /norestart /ChainingPackage FullX64Bootstrapper"
                DetectCondition="NETFRAMEWORK40"
                DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"/>
        </PackageGroup>
    </Fragment>
</Wix>
wix
bootstrapper
wix3.7
asked on Stack Overflow May 9, 2013 by Stealth Rabbi • edited Jul 3, 2013 by Peter Mortensen

2 Answers

8

There seem to be a lot of questions here.

It sounds like the root question is how to include the NETFX install embedded in your bundle. If so, you are correct that the WixNetfxExtension doesn't support that today. You do have to define your own copy and your copy is close (maybe copied from what is in the src\ext\NetFxExtension\wixlib). The only thing you need to change to get the NETFX embedded in your bundle is to set the ExePackage/@Compressed attribute to 'yes'. Or you could leave the Compressed attribute off and it will follow the compression of your Bundle element (which defaults to 'yes').

Second, the DetectCondition does determine if the package is on the machine. Burn will do the logical things based on whether the package is on the machine. For example, during install Burn will install the package if the package is absent but will do nothing if the package is already present. Of course, absent and permanent packages ignore requests to uninstall.

Third, the InstallCondition indicates whether the package should ever be installed on the machine. If it evaluates to true then the package can be installed (if absent and requested to be installed). If it evaluates to false the package is removed (if present).

Note: your registry search and conditions are a little different from what is used in the WiX toolset to detect NETFX. The following is the detection for NETFX the WiX toolset uses:

<util:RegistrySearch
    Id="NETFRAMEWORK40"
    Variable="NETFRAMEWORK40"
    Root="HKLM"
    Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
    Value="Install"
    Result="value" />

The DetectCondition is then just "NETFRAMEWORK40". That difference might explain the issues you are seeing.

answered on Stack Overflow May 9, 2013 by Rob Mensching • edited May 10, 2013 by Rob Mensching
2

I'm using the .NET Framework 4.5.2 in this answer. To include the .NET Framework as an offline installation:

  1. Include a PackageGroupRef element in your Chain:

    <Bundle>
        <Chain>
            <PackageGroupRef Id="NetFx452" />        
            <MsiPackage ... />
        </Chain>
    </Bundle>
    
  2. Download the Microsoft .NET Framework 4.5.2 (Offline Installer), and add it to your Bootstrapper Project. (I put it in a folder called "Resource".)

  3. Add the following Fragment:

    <Fragment>
        <util:RegistrySearchRef Id="NETFRAMEWORK45"/>
        <PackageGroup Id="NetFx452">
            <ExePackage Id="NetFx452"
                        Cache="no"
                        Compressed="yes"
                        PerMachine="yes"
                        Permanent="yes"
                        Vital="yes"
                        Name="NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
                        SourceFile="Resource\NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
                        DetectCondition="NETFRAMEWORK45"
                        InstallCommand="/q /norestart"  />     
        </PackageGroup>
    </Fragment>
    
answered on Stack Overflow May 1, 2015 by Chris Schiffhauer • edited May 2, 2015 by Chris Schiffhauer

User contributions licensed under CC BY-SA 3.0