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>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Stealth Rabbi
  • 10,156
  • 22
  • 100
  • 176
  • 1
    If I've read your question correctly, I think the title of your question is misleading. The issue isn't that `WixNetfxExtension` is failing to work. The issue is that you want to do something that isn't supported by `WixNetfxExtension` today. A more descriptive title for others might be: "How to include the .NET Framework compressed in a Bundle". If my answer below is completely wrong, feel free to disregard this comment. :) – Rob Mensching May 09 '13 at 16:42
  • @RobMensching, correct, the title was misleading. I am able to include the instaler loose/adjacent to the exe, which is what I want. however, my conditions are failing to detect if .NET is already installed, and I am not sure why. – Stealth Rabbi May 09 '13 at 17:38
  • Instead of adding the answer in the question you might as well add it as an answer. That is very much supported be Stackoverflow. (It is harder to see that there is an embedded answer in the question without reading the whole thing instead of browsing the actual answers) – default Nov 19 '13 at 13:45

2 Answers2

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.

Rob Mensching
  • 33,834
  • 5
  • 90
  • 130
  • I actually dont have a problem including the NET 40 installer. My main issue is that my detection conditions aren't working properly, and it alaways tries to install the package even if it has .net 4.0 installed on the system. – Stealth Rabbi May 10 '13 at 11:41
  • I updated my answer to include the NETFX 4 detection used by the WiX toolset. – Rob Mensching May 10 '13 at 14:27
  • After discarding my registry searches, and changing the DetectCondition to NETFRAMEWORK40, it still tries to install .NET4 on test machine (x64) that already has .NET 4 – Stealth Rabbi May 10 '13 at 15:45
  • Take a look at the Burn log file. I'm not sure what else to say. That condition works correctly for WiX toolset install. – Rob Mensching May 10 '13 at 15:56
  • I'm not sure where a burn log is. When I build the bootstrapper in VS, I only see build logs for candle and light. I added installer logs to my main question – Stealth Rabbi May 10 '13 at 16:12
  • Within my fragment tag, I try adding , but project indicates that it's an unresolved symbol ref. – Stealth Rabbi May 10 '13 at 16:44
  • To reference the element you'd want a `RegistrySearchRef` element, not a `PropertyRef` element. The Burn log is in %TEMP% and you did post a snippet from it. Somewhere higher there should be some mention of the search attempted and not found... or maybe you don't have the search actually being linked into your `Bundle`. – Rob Mensching May 10 '13 at 17:09
  • I didn't see anything about the search attempt failing; I'm guessing becuase the property name wasn't declared before, it just was believed false. Once I added the RegistrySearchRef, and added the util extension library, it worked! Correctly detects when it is and is not present. – Stealth Rabbi May 10 '13 at 17:26
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>
    
Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88