Bootstrapper - Čo to je a ako ho použiť

Publikoval Michal Kočí dňa 14.9.2007 o 18:42 v kategórii .Net

No, zase jeden z výstižných nadpisov, ale keď ide o nadpisy, tak moja kreativita je vždy na dne. Nevadí, prejdem k veci. Bootstrapper, a hlavne ten ktorý je súčasťou Visual Studia, je aplikácia, ktorá dokáže spustiť inú aplikáciu, pričom pred tým overí, ži sú splnené podmienky pre jej beh. Najmä preto sa používa pri tvorbe inštalačných balíčkov, ale jej použitie je možné aj v iných scenároch. V tomto príspevku poukážem na to čo to je Bootstrapper, ako ho použiť, ako pridávať podmienky, ako funguje a ako zautimatizovať jeho vytvorenie.

Čo je to Bootstrapper?

Bootstrapper je aplikácia napísaná v nie-manažovanom kóde, z čoho pramení hlavná výhoda - na počítači nepotrebuje mať nainštalovaný .Net Framework. Slúži na spustenie nejakej aplikácie z lokálneho disku alebo z URL a pred jej spustením dokáže skontrolovať podmienky pre jej beh. Ako podmienku si môžete predstaviť napríklad existensciu .Net Frameworku.

Prvý z možných scenárov

Z vyššie popísaného je jasný prvý možný scenár uplatnenia: Máte aplikáciu, ktorá k svojmu behu potrebuje aby na poťítači bol nainštalovaný .Net Framework. Povedzme, že túto aplikáciu nechcete inštalovať na klientský počítač, takže nebudete vytvárať inštalátor. Napriek tomu si chcete byť istý, že aplikácia bude spustená iba ak na klientskom počítači je nainštalovaný .Net Framework. Potom si vytvoríte bootstrapper, ako podmienku (lepšie povedané predpoklad, prerequisite) špecifikujete .Net. Keď niekto spustí Váš bootstrapper, tento najprv skontroluje či sú požiadavky splnené. Ak nie sú, snaží sa ich splniť (v tomto prípade nainštaluje .Net Framework a až potom pustí Vašu aplikáciu.

Nepripomína Vám to niečo? Počuli ste niekedy o ClickOnce? Už Vám to niečo pripomína?

Ako to funguje?

Teraz k tomu ako to funguje. Pred tým, než vygenerujete bootstrapper (či už si necháte pomôcť Visual Studiom alebo si malý a jednoduchý XML súbor napíšete sami), musíte mať pripravené všetky predpoklady, ktoré v skutočnosti sú ďaľšie malé a relatívne jednoduché XML súbory. Spustíte MSBuild a poukážete na Váš build skript, a MSBuild Vám vygeneruje jeden setup.exe - čo je v skutočnosti práve Váš bootstrapper upravený presne na mieru. Upravený v tom zmysle, že priamo v tomto exe súbor sú zakomponované skripty, ktoré overia či počítač spĺňa všetky predpoklady. O predpokladoch píšem trochu nižsie.

Odkiaľ sa však zoberú súbory potrebné na vyriešenie prípadov, kedy klientský počítať predpoklady nespĺňa? To je na Vás, alebo ich distribujete s Vašim bootstrapperom, alebo ich umiestnite niekde na webový server a bottstrapper si ich odtiaľ stiahne. Toto riešenie je niekedy veľmi vhodné, pretože Vy si môžete byť istý, že bootstrapper si stiahne len tie súbory, ktoré ozaj potrebuje. Takže v uvedenom prípade, ak je už .Net na klientskom počítači nainštalovaný, nebude si zbytočne ťahať vyše 20 megový inštalačný balíček. Ani ho nemusíte distribuovať spolu s Vašou aplikáciou.

Ďaľší z možných scenárov

Ďaľší z možných scenárov je použitie pre inštalačný balíček. Zjednodušene sa jedná o veľmi obdobný scenár ako prvý uvedený s tým rozdielom, že spúšťaná aplikácia je inštalátor aplikácie, nie aplikácia samotná. Môžete si tak pripraviť MSI (alebo si ho nechať vygenerovať Visual Studiom) a nechať ho zavolať bootstrapperom.

Toto Vám niečo nepripomína? Robili ste niekedy inštalátor ako projekt vo Visual Studiu? A zaškrtli ste si nejakú z Prerequisites v Properties dialógu? A nevygenerovalo Vám Visual Studio aj súbor setup.exe? Áno, toto je bootstrapper.

Ako vygenerovať bootstrapper?

Jedna z možností je vytvoriť si vo Visual Studiu projekt typu Setup a zaškrtnúť si všetky prerequisites, ktoré potrebujete. Toto riešenie je však vhodné najme pre druhý spomenutý scenár. Ak však chcete viac voľnosti pri konfigurácii alebo je Váš scenár podobný prvému uvedenému, potom je lepšie vygenerovať si XML súbor pre MSBuild a nakonfigurovať si bootstrapper presne podľa Vašich požadaviek.

MSBuild je defaultne nainštalovaný v adresári .Net Frameworku, štandardne adresár c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727. Spustíte ho jednoducho:

msbuild vas-skript.xml

Vo Vašom skripte potom uvediete najmä aké predpoklady majú byť splnené, odkiaľ ich má bootstrapper stiahnuť (pevne špecifikovaná URL, URL dodávateľa, rovnaká lokácia ako lokácia bootstrappera), čo má bootstrapper následne spustiť (obvykle Vaša aplikácia alebo Váš inštalačný balíček). Taktiež konfigurujete, kde má MSBuild hľadať súbory jednotlivých predpokladov. Tieto sú defaultne nainštalované v adresáric:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper.

V ukážkovom scenári chcem aby bootstrapper skontroloval prítomnosť .Net Frameworku a inej aplikácie(volajme ju napríklad Extend). Predpokladajme, že súbory bootstrappera (predpoklady ako aj kostru exe súbora) mám uložené lokálne v adresíri z ktorého MSBuild spúšťam (toto je kvôli tomu, že chcem aby mnou vytvorené predpoklady boli súčašťou CSV). Potom vas-skript.xml môže vyzerať nasledovne:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
      <BootstrapperFile Include="Microsoft.Net.Framework.2.0" />
      <BootstrapperFile Include="Extend.Aplikacia" />
   </ItemGroup>

   <Target Name="Bootstrapper">
      <GenerateBootstrapper 
         ApplicationFile="mojeMSI.msi"
         ApplicationName="Moja Aplikacia"
         ApplicationUrl="http://www.moj-server.sk/setup"
         BootstrapperItems="@(BootstrapperFile)"
         ComponentsLocation="Absolute"
         ComponentsUrl="http://www.moj-server.sk/setup"
         CopyComponents="True" 
         Culture="en" 
         OutputPath="output\"
         Path="$(MSBuildProjectDirectory)"
      />
   </Target>
</Project>

Všimnite si, že špecifikujem dva predpoklady (BootstrapperFile), že špecifikujem že ako predpoklady tak aj samotné mojeMSI.msi bude uložené na absolútej URL. No a teraz stačí zavolať MSBuild a on mi vygeneruje bootstrapper presne podľa mojich požiadaviek. Element GenerateBootstrapper je dobre zdokumentovaný v MSDN a obsahuje rovnako jednoduchý príklad takéhoto súboru.

Predpoklady (Prerequisites)

Fajn, takže už vieme čo je bootstrapper a ako si ho vygenerovať. Tiež už vieme, že ak potrebujeme overiť nejaké predpoklady (napríklad prítomnosť inej aplikácie) tak stačí pridať predpoklad ako podmienku pre beh našej aplikácie (či spustenie inštalácie). Ak sa pozrieme do adresára spomenutého vyššie, kde sa bootstrapper nachádza, tak v podadresári Packages si vieme pozrieť aké predpoklady sú pre nás predpripravené, ako napríklad .Net Framework 2.0, SQL Server Express, Crystal Reports či Microsoft Data Access Components. Čo však ak náš predpoklad prítomný nie je? No, nezostáva nič iné, ako si ho vytvoriť.

Základ je, vytvoriť si podadresár v podadresári Packages a v ňom vytvoriť súbor product.xml. Tento bude špecifikovať aká podmienka má byť splnená aby bootstrapper vyhodnotil tento predpoklad ako splnený (BypassIf), môžete definovať aj podmienku, ktorá keď je splnená tak nedovolí túto prerequisite nainštalovať (FailIf) a tak zabráni aj spusteniu Vašej aplikácie. No a potom musíte ešte pripraviť súbor package.xml v adresári pre každú kultúru (Culture), ktorú chcete podporovať. Kultúru berte ako istý typ jazykovej lokalizácie a do tohto súboru preto obvykle umiestňujete lokalizované texty.

Ukážkové súbory ukazujú ako môže vyzerať súbor, ktorý skontroluje či aplikácia Extend nie je už nainštalovaná a ak je, potom ju bootstrapper inštalovať nebude a vyhodnotí tento predpoklad ako splnený. Popis schém týchto dvoch súborov nájdete rovnako v MSDN.

Najprv súbor product.xml, v ktorom si všimnite najmä podmienku pre overenie či je aplikácia Extend už v systéme nainštalovaná (elementy BypassIf a MsiProductCheck) a čo sa tento prerequisite obsahuje a čo má byť spustené v prípade že prerequisite splnený nie je (elementy PackageFiles a Command).

<?xml version="1.0" encoding="utf-8" ?>
<Product xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper" ProductCode="Extend">
  <PackageFiles>
     <PackageFile Name="Media.msi"/>
  </PackageFiles>
  <InstallChecks>
    <MsiProductCheck Property="IsMSIInstalled" Product="{1771FDC8-D846-4B77-996A-C80DAD42C03F}"/>
  </InstallChecks>
  <Commands Reboot="Defer">
    <Command PackageFile="Media.msi" Arguments="">
      <InstallConditions>
        <BypassIf Property="IsMSIInstalled" Compare="ValueGreaterThanOrEqualTo" Value="3"/>
      </InstallConditions>
      <ExitCodes>
        <ExitCode Value="0" Result="Success"/>
        <ExitCode Value="1641" Result="SuccessReboot"/>
        <ExitCode Value="3010" Result="SuccessReboot"/>
        <DefaultExitCode Result="Fail" FormatMessageFromSystem="false" String="GeneralFailure" />
      </ExitCodes>
    </Command>
  </Commands>
</Product>

No a súbor package.xml vyzerá nasledovne a umiestniť ho treba do podadresára ktorého názov je totožný s jeho kultúrou, v tomto prípade "en".

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

K súboru product.xml pridáte ešte samotné súbory, v tomto prípade Media.msi. A to je všetko. Všimnite si najmä ProductCode v súbore product.xml, ktorý je použitý aj vo Vašom súbore pre MSBuild. To by mal byť jednoznačný identifikátor, podľa ktorého MSBuild nájde tú správnu prerequisite.

Konverzia predpokladov

Ako som spomenul v časti "Ako to funguje", pri generovaní bootstrapperu sa priamo do bootstrapperového exe súboru zakomponujú skripty, ktoré overia predpoklady. Tieto sú prekonvertované z XML do nejakého jazyka podobného Basicu. Toto nepotrebujete ani moc vedieť, ale aj tak pre zaujímavosť na čo sa pregeneruje uvedený predpoklad aplikácie Extend:

Begin Package
  Name="Extend"
  PackageCode="Extend.en"
  Begin Commands
    Reboot="Defer"
    Begin Command
      PackageFile="Extend\Extend.msi"
      Arguments=""
      Begin InstallConditions
        Begin BypassIf
          Property="IsMSIInstalled"
          Compare="ValueGreaterThanOrEqualTo"
          Value="3"
        End BypassIf
      End InstallConditions
      Begin ExitCodes
        Begin ExitCode
          Value="0"
          Result="Success"
        End ExitCode
        Begin ExitCode
          Value="1641"
          Result="SuccessReboot"
        End ExitCode
        Begin ExitCode
          Value="3010"
          Result="SuccessReboot"
        End ExitCode
        Begin DefaultExitCode
          Result="Fail"
          FormatMessageFromSystem="false"
          Text="A fatal error occurred during the installation of Extend"
        End DefaultExitCode
      End ExitCodes
    End Command
  End Commands
  Begin InstallChecks
    Begin MsiProductCheck
      Property="IsMSIInstalled"
      Product="{1771FDC8-D846-4B77-996A-C80DAD42C03F}"
    End MsiProductCheck
  End InstallChecks
  Begin PackageFiles
    Begin PackageFile
      Name="Extend\Extend.msi"
      Hash="4714EB78D9FAE9C4493A66C7CCDD06A3983A55D1"
      Size="5482496"
    End PackageFile
  End PackageFiles
End Package

Automatizácia

Vďaka tomu, že na vygenerovanie bootstrappera môžete použiť MSBuild, čo je konzolová aplikácia, je relatívne jednoduché začleniť jeho vygenerovanie do ľubovolného dávkového súboru. MSBuild navyše v prípade chyby naplní premennú errorlevel číslom rôznym od nuly, preto ak by ste chceli pustiť build a v prípade chyby no napríklad zastaviť a zobraziť chybovú hlášku, môžete použiť nasledovný fragment:

@echo off
set path=%path%;c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
msbuild /nologo vas-skript.xml
if %errorlevel% neq 0 (
  echo *** AN ERROR OCCURED
  echo *** There was an error while generating the Bootstrapper
  echo *** Please fix all errors in Bootstrapper and try again
  pause
  exit
)

Záver

Je dobré poznať, čo všetko sa Vám dostane na počítač spolu s Visual Studiom a toto je jedna z komponent, ktorá môže pomôcť v niektorých scenároch. My sme ju použili pri inštalácii a všetko funguje presne podľa našich predstáv.

Mohlo by ťa tiež zaujímať

Páčil sa ti príspevok?

Zdieľaj príspevok alebo si ho odlož na neskôr

Sleduj ma

Ak nechceš premeškať príspevky ako je tento, sleduj ma na Twitteri, alebo ak máš RSS čítačku, môžeš sledovať môj RSS kanál.