http://blogs.clariusconsulting.net/pga

Pablo Galiano's Blog

Go Back to
pga′s Latest post

Creating a bootstrapper for a VS Shell application

A bootstrapper is a program used to get the system prepared to install an application. Some applications have requirements in order to run properly.

This is the case for a VS Shell application that has the Visual Studio 2008 Shell Isolated Mode Redistributable package as a requirement.

Basically we need a bootstrapper that installs the Visual Studio 2008 Shell Isolated Mode Redistributable package first and if everything went fine, it redirects the call to our VS Shell application installer.

.Net Framework 2.0 includes the GenerateBootstrapper class to support the ClickOnce scenario. Of course we can use it in other scenarios, since this class is a msbuild task that can be easily added to our msbuild project.

The bootstrapper infrastructure that comes with .Net Fx 2.0 is generic and configurable by the notion of bootstrapper packages.

Bootstrapper packages are composed of one xml file (metadata that describes the package), a xml localization file and the msi/exe for the package itself.

These packages need to be copied to a certain location to be found by Visual Studio and the msbuild infrastructure.

We can see the installed packages on our system from Visual Studio with the Prerequisites… button:

 


prereq

This list is being populated from the %Program Files%\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages directory.

The first thing that we need to do is create the package for the VS Shell Redist.

These are two sample xml files for the bootstrapper package:

Product.xml

<?xml version="1.0" encoding="utf-8"?>
<Product ProductCode="Vs.Shell" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper”>
  <PackageFiles CopyAllPackageFiles="false">
    <PackageFile Name="vs_shell_isolated.enu.exe" />
  </PackageFiles>
  <InstallChecks>
    <RegistryCheck Property="VisualStudio" Key="HKLM\Software\Microsoft\VisualStudio\9.0" Value="ApplicationId" />
  </InstallChecks>
  <Commands Reboot="Immediate">
    <Command PackageFile="vs_shell_isolated.enu.exe" Arguments="/q" EstimatedInstallSeconds="2800">
      <InstallConditions>
        <BypassIf Property="VisualStudio" Compare="ValueEqualTo" Value="VisualStudio" />
      </InstallConditions>
      <ExitCodes>
    <ExitCode Value="0" Result="Success"/>
    <ExitCode Value="1641" Result="SuccessReboot"/>
        <ExitCode Value="3010" Result="SuccessReboot"/>
        <DefaultExitCode Result="Fail" String="GeneralFailure" FormatMessageFromSystem="true" />
      </ExitCodes>
    </Command>
  </Commands>
</Product>

Package.xml

<?xml version="1.0" encoding="utf-8"?>
<Package Name="Vs.Shell" Culture="Culture" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper”>
  <Strings>
    <String Name="Culture">en</String>
    <String Name="DisplayName">Vs Shell</String>
    <String Name="GeneralFailure">A fatal error occurred. The installation failed.</String>
  </Strings>
</Package>

Once we have the package created and correctly installed we can create a simple msbuild proj file that includes the GenerateBootstrapper task:

<Project DefaultTargets="Bootstrapper" xmlns="http://schemas.microsoft.com/developer/msbuild/2003″>
  <ItemGroup>
    <BootstrapperFile Include="Vs.Shell">
    <ProductName>Vs Shell</ProductName>
    </BootstrapperFile>
  </ItemGroup>

  <Target Name="Bootstrapper">
    <GenerateBootstrapper
      ApplicationFile=”MyVSShellApplication.msi”
      ApplicationName=”My Application”
      BootstrapperItems=”@(BootstrapperFile)”
      OutputPath=”.\”
      CopyComponents=”true”
      ComponentsLocation=”Relative”
      Culture=”en”
    />
  </Target>

  <Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
</Project>

So far so good, but now we have three files (bootstrapper (setup.exe), Vs Shell redist exe and our application msi).

We need to package these three files on single setup exe file that the user will download.

To package the files we can use the Microsoft IExpress technology.

And here is where we need to do some *ugly* hacks because of a directory structure problem with the GenerateBootstrapper task and IExpress (it doesn’t support adding directory structures)

After we compile our msbuild proj file a directory structure is created similar to:

  • Vs Shell
    • vs_shell_isolated.enu.exe
  • Setup.exe
  • MyVSShellApplication.msi

Unfortunately, the MSBuild task doesn’t provide the option to have the configuration resource use prerequisite installers found in the target directory, so you must manually update the appropriate resource file to remove the hard-coded path that looks for prerequisites in a sub-directory of the same name.

  • Open the Setup.exe program in Visual Studio’s resource editor
  • Double-click the resource named, SETUPCFG in the 41 folder
  • Search for the “Vs Shell\” string and delete the two occurrences that appear
  • Save the resource file and the Setup.exe executable will be updated automatically
  • Run iexpress
  • Create a new package by following the IExpress wizard’s steps and make sure to include the following files:
    1. The MyVSShellApplication.msi file
    2. The Setup.exe bootstrapper file
    3. The vs_shell_isolated.enu.exe file

 

Links:

Bootstrapper manifest generator:

http://www.codeplex.com/bmg

Packages documentation:

http://msdn2.microsoft.com/en-us/library/aa730839(vs.80).aspx

http://blogs.msdn.com/chrsmith/archive/2005/09/02/Rebooting-in-the-Bootstrapper.aspx

IExpress documentation:

http://www.microsoft.com/technet/prodtechnol/ie/ieak/techinfo/deploy/60/en/iexpress.mspx?mfr=true 

 

Happy VS Shell bootstrapping,

Pablo

Comments