Visual Studio's MSBuild utility includes a build task GenerateBootstrapper. This task will generate a custom Setup.exe that can download and install .NET, along with a raft of other components (including your own if you want). There's a great MSDN Magazine article about it here.
The list of components is extensible by defining your own "Package". Component packages are stored in %Program Files%\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages, and are defined using a custom XML schema. The Bootstrapper Manifest Generator project on CodePlex is an excellent tool for defining custom packages and it can also generate a MSBuild script for invoking GenerateBootstrapper.
Currently there are 9 different "stock" packages, which are:
Creating a standalone MSBuild project just to generate a bootstrap Setup.exe is very easy. Create a text file named Test.proj (the extension must end in "proj") and use the following XML:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<BootstrapperFile Include="Microsoft.Net.Framework.2.0">
<ProductName>Microsoft .NET Framework 2.0</ProductName>
</BootstrapperFile>
<BootStrapperFile Include="Microsoft.ReportViewer.8.0">
<ProductName>Microsoft Report Viewer</ProductName>
</BootStrapperFile>
</ItemGroup>
<Target Name="Bootstrapper">
<GenerateBootstrapper
ApplicationFile="WixBootstrapSample.msi"
ApplicationName="Wix Sample"
BootstrapperItems="@(BootstrapperFile)"
OutputPath=".\"
ComponentsLocation="HomeSite"
Culture="en"
/>
</Target>
</Project>
From the command line:
msbuild /target:Bootstrapper test.proj
This creates a Setup.exe that will check for .NET 2.0, download and install it if needed, then the same for the report viewer, and finally invoke WixBootstrapSample.msi. As a nice touch any dialogs displayed will show the title "Wix Sample Setup".
There are some gotcha's:
Download the sample project WixBootstrapCommandLineSample.zip. The sample depends upon the .NET 2.0 framework being installed.
Votive now uses MSBuild for its project file layout which means that adding a GenerateBootstrapper to the build process is straight-forward.
The key to this is editing the .wixproj file. You can either do this using notepad, or you can do this directly in Visual Studio. Instructions on doing this with Visual Studio can be found here.
When you open the .wixproj file you will see XML similar to the following:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<ProductVersion>3.0</ProductVersion>
<ProjectGuid>{a7744993-6892-4366-a2e3-b4828469c734}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>WixBootstrapSample</OutputName>
<OutputType>Package</OutputType>
<WixToolPath>C:\Program Files\Windows Installer XML v3\bin\</WixToolPath>
<Cultures>en-US</Cultures>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
<Cultures>en-US</Cultures>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<Cultures>en-US</Cultures>
</PropertyGroup>
<ItemGroup>
<Compile Include="WixBootstrapSample.wxs" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="C:\Program Files\Windows Installer XML v3\bin\WixUIExtension.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="ReadMe.txt" />
<Content Include="SampleFile.txt" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WiX\v3.0\Wix.targets" />
</Project>
The second last line, <Import Project="$(MSBuildExtensionsPath)\Microsoft\WiX\v3.0\Wix.targets" />, needs to be replaced with the following:
<ItemGroup>
<BootstrapperFile
Include="Microsoft.Net.Framework.2.0"
>
<ProductName>Microsoft .NET Framework 2.0</ProductName>
</BootstrapperFile>
</ItemGroup>
<Target
Name="Bootstrapper"
Inputs="$(OutDir)$(TargetFileName)"
Outputs="$(OutDir)\Setup.exe"
Condition=" '$(OutputType)'=='package' "
>
<GenerateBootstrapper
ApplicationName="WIX Bootstrap Sample"
ApplicationFile="$(TargetFileName)"
BootstrapperItems="@(BootstrapperFile)"
ComponentsLocation="HomeSite"
OutputPath="$(OutputPath)"
Culture="en-US"
/>
</Target>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WiX\v3.0\Wix.targets" />
<PropertyGroup>
<BuildDependsOn>$(BuildDependsOn);Bootstrapper</BuildDependsOn>
</PropertyGroup>
You will also want to change the value of the ApplicationName attribute of the GenerateBootstrapper element and add (or remove) BootstrapperFile entries.
After you've saved the changes and reloaded the project then whenever you build the project a Setup.exe file will be created in the same output directory as the .MSI (i.e. bin\Debug or bin\Release).
Download the sample project WixBootstrapSample.zip.
The sample depends upon Wix being installed at C:\Program Files\Windows Installer XML v3. This can be adjusted by using Notepad to editing the WixMondoSample.wixproj file.