Set up een eigen Setup

Het in Visual Studio aanwezige installer Setup project is om de één of
andere reden niet populair bij ontwikkelaars. Het wordt vaak als te beperkt
gezien. Volgens mij heeft dit gewoon te maken met de leercurve, Microsoft is er
goed in geslaagd de best uitgebreide functionaliteit goed te verbergen achter
vage iconen en iets te veel dialoogjes.

Enige tijd geleden heb ik al eens geblogged over het conditioneel uitvoeren van Setup logica.

Droste Effect

Nu wil ik stilstaan bij een ander redelijk onbegrepen stukje gereedschap:
Custom installers. Hiermee is het mogelijk om een redelijk standaard setup op te
schalen tot een uitgebreide setup door eigen code uit te voeren. Dat dit een
krachtige uitbreiding is, komt door de mogelijke interactie tussen de standaard
Setup en de eigen code.

Custom actions

We gaan dus een Setup uitbreiden met custom actions. Start eerst een
winform project en voeg daar een Setup project aan toe. We hebben nu twee
projecten in één solution:

P01

Voeg de output van de WinForm applicatie toe aan de setup:

P02

De rebuild van de totale solution is niet voldoende. Hercompileer en build de
setup expliciet. Zie dat de Setup succesvol gebouwd wordt:

P03

We gaan nu de Custom Installer toevoegen. Maak eerst een standaard
Library project aan:

P04

Verwijder de aanwezige klasse en voeg een Installer class toe:

P05

Override de methodes Install, Commit, Rollback en Uninstall. Plaats in de
methodes een MessageBox.Show (met dank aan de System.Windows.Forms
namespace):

namespace ClassLibrary
{
  [RunInstaller(true)]
  public partial class Installer :
  System.Configuration.Install.Installer
  {
    public Installer()
    {
      InitializeComponent();
    }

    public override void Install(IDictionary stateSaver)
    {
      base.Install(stateSaver);
      MessageBox.Show("Install");
    }
    public override void Commit(IDictionary savedState)
    {
      base.Commit(savedState);
      MessageBox.Show("Commit");
    }
    public override void Rollback(IDictionary savedState)
    {
      base.Rollback(savedState);
      MessageBox.Show("Rollback");
    }

    public override void Uninstall(IDictionary savedState)
    {
      base.Uninstall(savedState);
      MessageBox.Show("Uninstall");
    }
  }
}

Hercompileer de solution en fix eventuele fouten. Voeg hierna ook de
primary output van de library toe aan de Setup.

P06

Het enige wat nu nog gedaan moet worden, is het koppelen van de Custom
installer class aan de setup. Open dus in het Setup project de Custom Actions
Editor. Je ziet hier dezelfde mogelijke custom actions (Install, Commit,
Rollback en Uninstall).

P07

Er is nu nog geen Custom Action gekoppeld dus daar gaan we veranderingen
in aanbrengen. Selecteer (de root van de) Custom Actions en kies voor Add Custom Action via een rechter-muis-klik. Selecteer nu de primary output van de
Classlibrary (want hierin zit de Installer Class).

P08

Zie dat in één keer alle vier de actions toegevoegd zijn:

P09

Hercompileer nu het Setup project en start de installatie. Zie dat
tijdens de tweede helft van de installatie onze dialogen getoond worden. Hier
had dus uw eigen logica uitgevoerd kunnen worden

P10

P11   en 

Hierna is de setup compleet uitgevoerd. De-installeer nu de
applicatie en zie dat ook de UnInstall Action afgaat:

P13

Debuggen

Het is nu interessant om eens naar het debuggen te kijken. De
eenvoudigste manier zou een BreakPoint zijn. Helaas werkt dit niet voor een
Setup project. En “Attach to Process” zou ook een optie kunnen zijn maar dat is
best wel bewerkelijk. Het is eenvoudiger om via code een breakpoint uit te
voeren.

System.Diagnostics.Debugger.Break();

Hierna zal bij het uitvoeren van de ‘breakpoint’ gevraagd worden om
Visual Studio te starten en kan de code de uitvoer alsnog gedebugged worden.
Vergeet deze achteraf niet te verwijderen!

P14

Rollback

Mocht tijdens de install nu toch gekozen worden om de totale
installatie terug te draaien, creëer dan een InstallerException.

public override void Install(IDictionary stateSaver)
{
  base.Install(stateSaver);
  throw new InstallException("Helaas...");
  //MessageBox.Show("Install");
}

Hiermee zal de opgegeven tekst getoond worden, en zal de rollback uitgevoerd
worden. De setup is hierna teniet gedaan. Zorg er dus voor dat al eventueel
uitgevoerde logica ook verwijderd wordt.

P15   P16

Doorgifte parameters

Het is tevens mogelijk om gegevens door te geven aan de custom
installer. Pas hiervoor de Custom Action aan.

Eerst moeten we de doorgifte instellen. Vul daarvoor de CustomActionData in.
Als voorbeeld geef ik hier de TargetDir door, dat is de map waarin de applicatie
geïnstalleerd wordt. Het let overigens heel nauw hoe deze doorgegeven worden.
Let dus goed op de back-slash en de quotes.

P17

Daarna moeten we de code op de doorgegeven waarde laten
reageren:

public override void Install(IDictionary stateSaver)
{
  base.Install(stateSaver);
  string value = Context.Parameters["TargetDir"];
  if (!string.IsNullOrEmpty(value))
  {
    MessageBox.Show("Install " + value);
  }
  else
  {
    MessageBox.Show("Install --");
  }
}

Nu zal de map doorgegeven worden en kan hier dus extra op gereageerd worden met eigen code.

P18

Kijk hier voor een voorbeeld waarin uitgelegd wordt hoe ook tekst doorgegeven kan worden.

Conclusie

In enkele minuten is een vrij statische installatie veranderd in een
weelderige Setup waarin eigen code uitgevoerd kan worden. Hierdoor zijn er geen grenzen meer zijn aan de mogelijkheden om de gebruiker met succes te begeleiden tijdens de installatie en de de-installatie.