Een introductie van Windows Installer XML
Twee jaar geleden heeft Microsoft de eerste stappen gezet in de wereld van de open source community. Via SourceForge.net heeft Microsoft onder de Common Public License - die op http://opensource.org/licenses/cpl.php is na te lezen - WiX gratis beschikbaar gesteld. WiX staat voor Windows Installer Xml (zie de WiX website: http://wix.sourceforge.net/) en is een set van programma’s waarmee Windows Installation Packages gemaakt kunnen worden.
Achtergrond
Een Windows Installation Package, ook wel bekend als MSI, is een database die bestanden en meta-informatie bevat die nodig zijn om een applicatie te installeren in een Windows omgeving. Met behulp van de Windows Installer Service (msiexec.exe) kunnen deze MSI databases “uitgevoerd” worden.
In de markt zijn verschillende leveranciers die producten leveren om Windows Installation Packages te maken. Voorbeelden hiervan zijn o.a. InstallShield en Wise Installer. Microsoft biedt met Visual Studio ook de mogelijkheid om Windows Installation Packages aan te maken.
Met WiX komt Microsoft met een alternatief voor deze bestaande producten. WiX is een toolset die al enkele jaren intern binnen Microsoft gebruikt wordt. Door de jaren heen zijn er verschillende ontwikkelteams binnen Microsoft geweest die WiX zijn gaan gebruiken voor het bouwen van installation packages. Voorbeelden hiervan zijn o.a. het SQL Server-team en het BizTalk-team.
Windows Installer Technology
Om WiX en vooral de WiX sourcebestanden goed te kunnen begrijpen is het nodig om een aantal begrippen en basisconcepten van de Windows Installation Technology te kennen.
Elk Windows Installation Package bestaat minimaal uit een MSI-bestand. Dit bestand bevat een database, een summary information stream en één of meerdere data streams. De database bevat bestanden en meta-informatie die nodig zijn om een applicatie te installeren in een Windows omgeving. De summary information stream bevat algemene informatie over het Windows Installation Package en wordt onder ander door de Windows Explorer gebruikt om deze informatie te tonen. De data streams worden tijdens de installatie gebruikt en bevatten bijvoorbeeld plaatjes of custom action DLL’s.
Een Windows Installation Package kan verder bestaan uit externe bestanden of cabinet bestanden. Een cabinet bestand bevat één of meer gecomprimeerde bestanden die tijdens de installatie nodig zijn. De meta-informatie in de database beschrijft in dat geval wat er in de externe bestanden of cabinet bestanden staat.
Een Windows Installer file kan verschillende extensies hebben. De meest voorkomende extensies zijn MSI en MSM. De extensie geeft aan dat het om een bepaald type Windows Installer-bestand gaat. Een MSI bestand is een Windows Installer database en kan met behulp van de Windows Installer Service direct uitgevoerd worden. Een MSM bestand is een Windows Installer Merge module en kan samen met andere Windows Installer Merge modules en/of een Windows Installer database tot een nieuwe Windows Installer database samengevoegd worden.
Binnen de Windows Installer Technology en specifiek binnen een MSI database is een aantal begrippen belangrijk. Omdat deze begrippen ook binnen WiX terugkomen, volgt hier een kort overzicht met de betekenis van deze begrippen:
- Package: Een package bevat alle informatie die de Windows Installer service nodig heeft om een applicatie te installeren of te deïnstalleren. Een package bevat zowel de bestanden als de meta-informatie die aangeeft hoe de applicatie geïnstalleerd en gedeïnstalleerd moet worden. Een package bestaat uit een MSI-bestand en eventueel één of meerdere externe bestanden.
- Product: Een product is een bepaalde versie van een applicatie die geïnstalleerd moet worden. Denk hierbij bijvoorbeeld aan Visual Studio 2005 of SQL Server 2005.
- Feature: Een feature is verzameling van functionaliteiten die onderdeel uitmaken van het product. Een feature is tevens het kleinst installeerbare onderdeel in een Windows Installation Package. Tijdens de installatie kan de gebruiker kiezen een feature wel of niet te installeren. Denk hierbij bijvoorbeeld aan de mogelijkheid om tijdens installatie van Visual Studio te kiezen Visual C# wel te installeren maar bijvoorbeeld Visual Basic niet.
- Component: Een component is een onderdeel van een feature dat geïnstalleerd kan worden. Een component kan bestaan uit één of meer bestanden, snelkoppelingen, registry entries, enz. Door het selecteren van een feature wordt bepaald welke componenten er geïnstalleerd moeten worden.
Deze begrippen hebben een relatie met elkaar. Een package bevat de informatie over één product. Het product bestaat uit één of meer features. Een feature kan uit andere features bestaan of bestaat uit één of meer componenten. Een component ten slotte kan uit een aantal verschillende onderdelen bestaan. Het is mogelijk dat een component in verschillende features gebruikt wordt. In Fig. 1 wordt deze relatie schematisch weergegeven.

Fig. 1: Relatie begrippen
De toolset
De WiX toolset - voor dit artikel is gebruik gemaakt van versie 2.0.4221.0 - bestaat uit een aantal tools waarvan de twee belangrijkste zijn
- de compiler (Candle.exe) en
- de linker (Light.exe).
De compiler wordt gebruikt om de WiX source-bestanden om te zetten naar object-bestanden. De linker verwerkt een of meer object bestanden tot een Windows Installation Package.
Andere tools die in de toolset zitten zijn:
- een decompiler (Dark.exe) waarmee bestaande MSI of MSM bestanden omgezet kunnen worden naar WiX source bestanden;
- een tool (Lit.exe) om libraries te maken;
- een tool (Tallow.exe) om op basis van een directory-structuur een WiX sourcecode-bestand te genereren;
- een update tool (WixCop.exe) om oude WiX source bestanden te upgraden naar de laatste schema definitie.
Versie 3 van de WiX toolset zal worden uitgebreid met een tweetal nieuwe tools. Een tool (Heat.exe) die op basis van een directory-structuur een WiX source code bestand kan genereren. Dit lijkt op de tool Tallow.exe. Heat.exe heeft echter de mogelijkheid om een eigen plug-in toe te voegen om invloed uit te oefenen op de manier waarop het WiX sourcecode-bestand wordt gegenereerd. Hiermee komt Tallow.exe te vervallen.
De tweede tool die wordt geïntroduceerd is een tool (Smoke.exe) om MSI of MSM bestanden te testen/valideren.
Candle, Light, Dark, Lit, Tallow … de Wix tools
De manier waarop de WiX compiler en linker samenwerken verschilt niet veel van de manier hoe andere typen programma’s worden gemaakt. Dit is weergegeven in Fig. 2. Bij het ontwikkelen van programma’s schrijft de ontwikkelaar sourcecode die tot een executable of library wordt gecompileerd. Tijdens de compilatie kunnen externe resources mee gecompileerd worden om tot één eindproduct te komen (de rechter tak in Fig. 2).
De WiX sourcecode (een XML-file) wordt op een soortgelijke manier verwerkt. Als eerste wordt de setup code omgezet naar een object-bestand. De compiler fungeert hierbij als preprocessor. Er wordt gevalideerd of de WiX source code well-formed XML is en of de sourcecode voldoet aan het WiX schema. Vervolgens worden de source-bestanden gecompileerd naar een WiX object-bestand.
Het object-bestand wordt vervolgens als input gebruikt door de linker om te bepalen welke externe resources (executables, libraries, plaatjes, copyright statements, enz.) er in het MSI of MSM bestand moeten komen (de linker tak in Fig. 2).

Fig. 2: Werking compiler/linker.
Alle tools in de WiX toolset zijn commandline tools. Met behulp van argumenten kunnen deze tools gestuurd worden. Dit biedt o.a. de mogelijkheid om deze tools te integreren in een build-proces om geautomatiseerd Windows Installer Packages te creëren.
Naast deze toolset is er in de open source community en vanuit Microsoft een aantal initiatieven gestart om het gebruik van WiX te vergemakkelijken. Een voorbeeld hiervan is Votive (zie http://wix.sourceforge.net/). Votive is een add-in voor Visual Studio die het mogelijk maakt om WiX source-bestanden vanuit Visual Studio te bewerken. Het biedt IntelliSense ondersteuning, maakt het mogelijk om WiX bestanden te groeperen in Visual Studio projecten, MSI te bouwen vanuit Visual Studio, enz. Vanaf versie 3 zal er ook ondersteuning voor MsBuild worden geboden.
Een ander voorbeeld is WiX Edit (zie http://wixedit.sourceforge.net/). WiX Edit is een ontwikkelomgeving voor WiX. Eén van de sterke features is dat het een dialog editor biedt waarmee de GUI voor een Windows Installer Package gedefinieerd kan worden.
Naast de ondersteuning die vanuit het WiX en Votive team worden geboden voor MsBuild is er een workspace op GotDotNet met MsBuild tasks (met de naam Microsoft Services (UK) Enterprise Solutions Build Framework). Hier zitten ook enkele WiX en MSI tasks tussen.
Voorbeeld
Nu de basisconcepten van MSI uiteengezet zijn en de WiX toolset is geïntroduceerd, kan er gekeken worden naar de WiX sourcecode. In listing 1 wordt een voorbeeld gegeven van een WiX source-bestand. In dit voorbeeld wordt een MSI gedefinieerd die een bestand (File.txt) in een directory (MyDir) onder de “Program Files” directory installeert.
01 02 xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
03 04 Language="1033" Manufacturer="Me"
05 UpgraceCode="{GUID}">
06
07
08
09
10
11
12
13
14 15 DiskId="1" Name="File.txt"
16 src="File.txt" />
17
18
19
20
21
22
23
24
25
26
Listing 1.
(NB: Het voorbeeld is niet direct te gebruiken. Eerst moet de tekst ‘{GUID}’ vervangen worden door een echte guid.)
Een WiX sourcecode-bestand is een XML-bestand dat voldoet aan het WiX schema. Binnen een Windows Installer database worden foreign keys gebruikt om relaties te leggen tussen verschillende onderdelen. In een WiX sourcecode-bestand worden deze relaties o.a. gerealiseerd door het nesten van elementen. Zoals in het voorbeeld (zie listing 1) te zien is, komen de 4 belangrijkste begrippen (Product/Package/Feature/Component) uit de Windows Installer Technology terug in de WiX sourcecode.
Afhankelijk van het feit of er een Windows Installer database of een merge module gecreëerd wordt, is het eerste (child) element binnen de root van een WiX source-bestand respectievelijk een Product of Module element. Dit is het eerste element in een WiX sourcecode-bestand dat overeen komt met een tabel in de Windows Installer database.
Het Product of Module element beschrijft het product (of onderdeel van het product) dat geïnstalleerd moet worden. Hier worden bijvoorbeeld de naam en de versie gespecificeerd.
Een belangrijk attribuut bij het Product/Module element is het Id/Guid attribuut. Dit attribuut wordt gebruikt om de productcode van de MSI/MSM te definiëren. De productcode wordt o.a. gebruikt door de Windows Installer Service om te valideren of het product al op de omgeving geïnstalleerd is.
De Windows Installer Service staat niet toe dat er twee verschillende programma’s worden geïnstalleerd met dezelfde productcode. Bij het uitvoeren een MSI met dezelfde productcode als een MSI die al geïnstalleerd is, zal de installatie direct worden afgebroken. Een productcode zal alleen in de volgende gevallen veranderd moeten worden:
- Bij een nieuwe versie van het product waarbij site-by-site installatie van de oude en nieuwe versie noodzakelijk is.
- Indien een upgrade van een bestaande versie van het product mogelijk moet zijn.
Naast het specificeren van een productcode is het mogelijk om bij het Product element een UpgradeCode te specificeren. Een upgradecode is nodig om bij het uitleveren van een nieuwe versie van het product de mogelijkheid te hebben om een al bestaande versie van het product op het systeem bij te werken i.p.v. het installeren van een tweede versie van het programma. De oude en nieuwe versie van de MSI moeten in dit geval dezelfde upgradecode hebben maar een verschillende productcode. Het is aan te raden om de MSI vanaf de eerste versie te voorzien van een upgradecode.
Om een product te upgraden moet de Windows Installer Service verteld worden dat het Windows Installer Package dat uitgevoerd moet worden een upgrade is. Dit kan bereikt worden met het volgende commando: msiexe.exe /i sample.msi REINSTALL=ALL.
Om een product te upgraden moet je dat de Windows Installer Service vertellen
Het Package element bevat informatie die in de Windows Installer information stream wordt geplaatst. De packagecode wordt bijvoorbeeld in het Revision Number veld opgeslagen en het Manufacturor attribuut word in het Author veld gezet. Zie ook de summary properties van een MSI bestand in de Windows Explorer.
Het Id attribuut op het Package element wordt gebruikt als packagecode. Een packagecode wordt gebruikt om een MSI bestand te koppelen met een product. Elk uniek MSI bestand moet een eigen packagecode hebben. Als een MSI is gewijzigd en de packagecode is niet aangepast, kan het zijn dat de Windows Installer Service niet de laatste versie van het package gebruikt tijdens installatie.
In WiX kan het Id attribuut de waarde “????????-????-????-????-????????????” (of “*” vanaf versie 3 van WiX) worden gegeven. Dit zorgt ervoor dat tijdens compilatie automatisch een nieuwe guid wordt gegenereerd.
De feature om automatisch guids te genereren is erg handig voor het wijzigen van de packagecode. Hiermee wordt voorkomen dat het wijzigen van de packagecode wordt vergeten. Het gebruik van deze feature voor het aanpassen van de productcode is afhankelijk van de voorwaarden die aan de MSI worden gesteld. Indien side-by-side installatie van verschillende versies nodig is, dan kan deze feature ook goed voor de productcode gebruikt worden.
Alle bestanden, registry entries, virtual directories, snelkoppelingen, enz. die geïnstalleerd moeten worden en bij elkaar horen, kunnen gegroepeerd worden in een component. In listing 1 wordt een component gedefinieerd met een enkel bestand.
Het Component element heeft ook een Guid attribuut. Dit attribuut heeft verder geen speciale betekenis maar wordt net als alle andere id’s in de Windows Installer database gebruikt om naar te verwijzen.
Als laatste wordt een feature element gedefinieerd. Een feature is het kleinst installeerbare onderdeel van een Windows Installer Package. Feature elementen verwijzen naar Component elementen die onderdeel uitmaken van de feature.
Overwegingen
MSI’s kunnen heel simpel zijn, zoals in het voorbeeld. Vaak bestaat een MSI uit een verzameling van vele bestanden, snelkoppelingen, configuratiebestanden, enz. Complexe installatieacties kunnen nodig zijn om de applicatie correct te installeren. Denk hierbij aan het registreren van componenten, aanpassen van configuratiebestanden, installeren van databases, enz. Vaak is hierbij een uitgebreide GUI nodig om de installatiestappen te kunnen sturen.
Het opzetten van een MSI met een eigen GUI en complexe installatiestappen kost tijd. Dit is dan ook niet iets wat op het laatste moment tijdens het project nog ‘even’ gedaan kan worden. Het is aan te raden om parallel aan de ontwikkeling van de applicatie de MSI te ontwikkelen.
Het opzetten van een MSI met een eigen GUI en complexe installatiestappen kost tijd
Bij grote softwareprojecten is het handig de installatiesoftware modulair op te bouwen. Merge modules kunnen dan uitkomst bieden. Door gebruik te maken van merge modules kunnen verschillende teams tegelijk werken aan de installatie software. Op een later tijdstip kunnen deze merge modules samengevoegd worden tot een MSI die het hele product bevat. Een tweede voordeel van merge modules is dat deze herbruikt kunnen worden bij het maken van een andere Windows Installer Package. Net zoals componenten tussen verschillende applicaties worden herbruikt, kunnen merge modules voor installatie software worden herbruikt.
Met WiX is het mogelijk om een GUI te definiëren voor een Windows Installation Package. Hoewel de WiX toolset zelf geen design tool bevat die gebruikt kan worden om een GUI te definiëren, is er via de open source community toch het één en ander beschikbaar om dit te vergemakkelijken. Er zijn WiX GUI editors en WiX GUI libraries beschikbaar die het eenvoudiger en onderhoudbarder maken om een MSI van een GUI te voorzien.
In dit artikel zijn de basisbeginselen van WiX behandeld. Naast de mogelijkheden zoals gegeven in het voorbeeld biedt WiX nog veel meer mogelijkheden. WiX biedt o.a. de mogelijkheid om:
- launch conditions te definiëren
- een GUI te definiëren
- custom actions uit te voeren
- websites te creëren
- databases aan te maken en SQL-scripts uit te voeren
- en meer…
Conclusie
Hoewel de WiX toolset geen gebruiksvriendelijke ontwikkelomgeving levert zoals een aantal andere grote spelers in de markt, biedt WiX de ontwikkelaar toch de mogelijkheid op een simpele manier Windows Installer Packages te maken.
Met WiX geldt net als met andere softwarepakketten dat er goed nagedacht moet worden over de installatiesoftware. Wil ik wel of niet side-by-side installation van mijn product ondersteunen? Uit welke (herbruikbare) onderdelen bestaat mijn installatie? Ga ik in de toekomst updates beschikbaar stellen of lever ik alleen nieuwe versies uit?
Begin tijdig met het bouwen en testen van de installatiesoftware. Integreer het zoveel mogelijk in een build-proces om met enige regelmaat de installatiesoftware te kunnen bouwen en testen.
Houd de open source community in de gaten: er worden steeds meer initiatieven gestart om het gebruiksgemak van WiX te verbeteren.