April 17, 2007

BootStrapper BootStrapping

Bootstrapping is the creation of a wrapper installer around already existing installars or files.
It's useful if you have multiple installation files that you'll like the user to install in on step.

The Bootstrapper itself is a .exe installer file, it also may have .SED file which contains details of the contents of the .exe.

There are a few applications out there to generate a bootstrapper, the most simple I've seen is the an app called IEXpress.
IExpress
Is actually installed on windows (System32/iexpress.exe).
This creates an installer, you tell it what files you wish it to include in the installation.
I've only played with this so far and it appears to me that the isntaller can only install upto 2 setup.exes. You can include as many files as you like, but the files cannot have the same name, because of this you will probably need to rename your setup.exes to something else because you cannot have 2 files with the same name.
After you've included all the files you wish to run the next step asks you which files you wish to run, at this stage it looks like you can only specify upto 2 .exe installer files (there maybe a way around this, by editing the .sed file afterwards).
Also the final step I recommend telling the bootstrapper to use full files paths, this seems to ensure it works.

Visual Studio
In Visual Studio the BootStrapper is read in as an XML file. Visual Studio has a set BootStrapper XML file which it reads, below I will describe how to use this default bootstrapper and then I will describe how to create your own.
Using the BootStrapper in Visual Studio
Visual Studio also has a Bootstrapper, it's actually the Launch Conditions Editor in the Setup Project. The prerequisites are what your looking for, you'll see .NET is there by default.

By right clicking the Setup Project and bringing up the Properties dialog you'll a prerequisites button, this launches another dialog which lists the prerequisites, only the default ones are there.

There is a snag with this however you can to add your own you'll need to create your own BootStrapper XML file
Create your own BootStrapper file
There are 2 ways to create the XML file
1. Write the XML file yourself and copy to the correct location:
you'll need to follow the instructions in the .zip found in the BootStrapper SDK
2. You can use an Community UI (BMG) to write the bootstrapper for you (note the web installer doesn't work funnily enough, the msi does, the program can then be found at C:\Program Files\Microsoft\Bootstrapper Manifest Generator\BMG.exe).
It allows you to add .msi files, .exe files and apply conditions for them. It also installs the bootstrapper xml file for you after, this makes it available in Visual Studios Setup Project Prerequisite dialog that I mentioned earlier.
Here's a complete description of how to install you Custom Prerequisite.
Use the Visual Studio 2005 Bootstrapper to Kick-Start Your Installation - This article is the complete version and is not msdn, Also describe Custom bootstrapping.
Adding Custom Prerequisites.

MSBuild GenerateBootStrapper Task
After you've created your Visual Studio BootStrapper you can use it with MSBuild with the GenerateBootstrapper Task.
This MSBuild task allows you to include your custom prerequisite in any Visual Studio Project.
So if you wish to create a Bootstrapper for your installer using MSBuild it's the same thing as Adding Prerequisites to your Setup Project using the Project->Properties->Prerequisite dialog.
You'll still need to have your prerequisites created and installed beforehand.
Here's and example of a project to create a BootStrapper using 2 Prerequisites:


<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{7447AF9B-33E3-41AE-9D88-833704524543}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Content Include="MyOriginalInstaller.msi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Target Name="Bootstrapper">
<GenerateBootstrapper
ApplicationFile="MyOriginalInstaller.msi"
ApplicationName="MyInstallerName"
BootstrapperItems="@(BootstrapperFile)"
ComponentsLocation="Relative" Culture="en" FallbackCulture="en-IE" CopyComponents="True"
Validate="False"
OutputPath="$(OutputPath)"
Path="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper" />
</Target>
<ItemGroup>
<BootstrapperFile Include="Microsoft.Net.Framework.2.0">
<ProductName>.NET Framework 2.0</ProductName>
</BootstrapperFile>
<BootstrapperFile Include="ProjectAggregator2">
<ProductName>ProjectAggregator2.msi</ProductName>
</BootstrapperFile>
</ItemGroup>
</Project>


We're creating a BootStrapper called MyInstaller.msi.
We're setting our main Installer (the one whose Gui appears) to be "MyOriginalInstaller.msi".
We include this same main installer "MyOriginalInstaller.msi" in the current project, it appears that it must be found in the current project in order for this to work.
We include to pre-requisites which get installed beforehand, their ProductName must be identical to the folder name that appears in their installation location
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages
e.g.
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\ProjectAggregator2.msi\

ClickOnce FAQs (installsite.org)

April 16, 2007

dotNET Custom Attributes

Attributes those snippets of code you see in .NET classes in square brackets at the top of Class or Method, one of the most common examples is [WebMethod] to indicate that the current method is a WebMethod.
The Attribute is in fact a class that inherits from System.Attribute. The Attribute is read in at Runtime, Reflection takes care of this. Attributes are useful for flagging types, conditions when and when not to use certain methods like the WebMethod.

April 04, 2007

WiX - Windows Installer XML

Latest Release ('Rosario' November CTP msdn) now has Visual Studio Integration.
WiX Tutorial (tramontana).
WiX documentation (sourceforge).
WiX and Visual Studio (msdn forum).
WiX integration in Visual Studio using Votive (Votive blog).
WiX integration (msdn).
WiX Forum.
Building setup packages for Visual Studio project templates and starter kits (Aaron Stebner's WebBlog)
WiX Tallow tool

WiX is a methodology to write installers.
WiX has a compiler/linker (candle/light) which may give the installer writer some validation before deployment.
The contents of the end installer (.msi) are edited using an XML file.
I haven't found WiX to be advantageous over the ordinary Visual Studio Setup Project.
Visual Studios SDK has a project template (from Votive) for creating WiX installers. This project template gives you the skeletol wix file to start and the build commands are built into the project, all you've to do is create new GUIDs ,these guids are only for the installer, they've nothing to do with your applications GUIDs, the WiX compiler, candle.exe, will complain if you fail to change one anyway.
The addition of items to install is done be editing the WiX xml file! if you choose to use it with Visual Studio , the Votive version (present Wix 2) then you'll get Intellisence, that with the Candle compiler are very useful but editing xml files is very tedious.
You'll also note that this version does not support integrated Visual Sourcesafe in Visual Studio, I found this a disadvantage. However WiX 3 (presently in developer status) does have this but lacks other vital components at present, such as it does not support the gui components you require for user input in the installer. In WiX 2 these are provided by the SDK in the wixui.dll.

All in all I don't think WiX is up to scratch just yet but WiX 3 does look promising.

There's a tool now called Tallow which included in the WiX SDK, apparently it's a command line tool that allows you to create a WiX installer be passing in you file locations and registry settings on the command line.

WiX pre-processor table (these items can be added to your WiX file, they are replaced at compile time).

Preprocessor VariableExample Variable UseExample Variable Value
var.<Project>.ConfigurationName$(var.MyApp.ConfigurationName)Debug.NET
var.<Project>.ProjectDir$(var.MyApp.ProjectDir)C:\code\msdn\MyApp
var.<Project>.ProjectDosFileName$(var.MyApp.ProjectDosFileName)MYAPP.CSP
var.<Project>.ProjectExt$(var.MyApp.ProjectExt).csproj
var.<Project>.ProjectFileName$(var.MyApp.ProjectFileName)MyApp.csproj
var.<Project>.ProjectName$(var.MyApp.ProjectName)MyApp
var.<Project>.ProjectPath$(var.MyApp.ProjectPath)C:\code\msdn\MyApp\MyApp.csproj
var.<Project>.TargetDir$(var.MyApp.TargetDir)C:\code\msdn\MyApp\obj\Debug
var.<Project>.TargetDosFileName$(var.MyApp.TargetDosFileName)MYAPP.EXE
var.<Project>.TargetExt$(var.MyApp.TargetExt).exe
var.<Project>.TargetFileName$(var.MyApp.TargetFileName)MyApp.exe
var.<Project>.TargetName$(var.MyApp.TargetName)MyApp
var.<Project>.TargetPath$(var.MyApp.TargetPath)C:\code\msdn\MyApp\obj\Debug\MyApp.exe
var.SolutionDir$(var.SolutionDir)C:\code\msdn\MySetup
var.SolutionDosFileName$(var.SolutionDosFileName)MYSETUP.SLN
var.SolutionExt$(var.SolutionExt).sln
var.SolutionFileName$(var.SolutionFileName)MySetup.sln
var.SolutionName$(var.SolutionName)MySetup
var.SolutionPath$(var.SolutionPath)C:\code\msdn\MySetup\MySetup.sln