Úvod
U každé profesionální desktopové aplikace je zvykem, aby měla svůj instalátor. Instalátor je program, který v podobě průvodce pomůže uživatelům aplikaci správně připravit k použití na cílovém počítači. Pod pojmem “správně připravit” si můžeme představit kombinaci následujících úkonů:
- Shromáždění informací od uživatele (potvrzení licenční smlouvy, zadání jména, společnosti, případně sériového čísla, výběr instalovaných součástí)
- Zkopírování souborů aplikace do zvolené (nebo výchozí) složky
- Nainstalování podpůrných souborů (.NET Framework, DirectX, knihovny třetích stran, apod.)
- Konfigurace aplikace (zaregistrování služby, rozhraní COM, asociace souborů, zápis hodnot do registru)
- Vytvoření zástupců v nabídce Start, na pracovní ploše, nebo jinde
- Volitelná instalace dalších aplikací (Adobe Reader)
Úkolem instalátoru je rovněž odstranění již nainstalované aplikace z počítače a to buď kompletně, nebo s ponecháním některých souborů (konfigurační a/nebo datové soubory, uložené hry, atd.), a možnost přidání, odebrání, nebo opravení součástí aktuálně nainstalované aplikace (většinou u velkých produktů jako Microsoft Office).
Zajišťovat tuto funkčnost v aplikaci samotné by byl velmi komplexní a hlavně zcela zbytečný úkol, přesto to některé nevychované aplikace (µTorrent) takto dělají.
Běžně používané produkty pro tvorbu instalátorů
Existuje celá řada produktů, které umí instalátor vytvořit buď pomocí “naklikání” vlastností (vizuálně), pomocí skriptu, nebo kombinací obojího.
*Pouze s použitím produktů třetích stran **1=nejjednodušší, 5=nejsložitější
Přestože Windows Installer je technologie ve Windows velmi rozšířená (nejen produkty Microsoftu, tuto technologii využívá např. i výše zmiňovaný InstallShield a Wise Installation Studio), mám s ní velmi špatné zkušenosti hlavně proto, že je neskutečně komplexní a je schopná nadělat v systému takový bordel, že už se ho nezbavíte. Bohužel pokud chcete aby se vaše aplikace honosila logem Designed for Windows, musíte pro instalaci využívat tuto technologii.
Co očekávat od instalátoru
Společná množina funkcí různých instalátorů je víceméně stejná, jednotlivé instalátory se ve většině případů liší pouze drobnostmi. Přesto je však při výběru instalátoru dobré vědět, jaké funkce musí bezpodmínečně umožňovat, což najdete v následujícím seznamu.
- Kopírování souborů přímo z instalačního archivu (vhodné pro online distribuci) nebo z externího umístění (vhodné pro distribuci na instalačním médiu)
- Vytváření zástupců v nabídce Start, na ploše, nebo jinde (panel Snadné spuštění) a to jak pouze pro aktuálního uživatele, tak pro všechny uživatele
- Kontrola spuštěných aplikací před zahájením instalace (zda-li instalovaná aplikace není spuštěna)
- Možnost výběru typu instalace a instalovaných součástí
- Možnost ověřovat nastavení instalace v libovolném kroku a případně ukončit instalaci
- Možnost odinstalování aplikace
- Možnost instalování několika současně existujících verzí stejné aplikace, nebo upgrade již nainstalované aplikace
- Zápis hodnot kamkoliv do registru (vytváření klíčů a hodnot pokud neexistují)
- Spouštění programů a vyhodnocování návratových hodnot
- Podpora lokalizace
- Podpora 32-bitových i 64-bitových systémů
- Podpora operačních systémů minimálně od Windows 2000 až po Windows 7
Všechna tato kritéria do puntíku splňuje Inno Setup, a proto se budu v dalších odstavcích soustřeďovat pouze na tento produkt.
Úvod do instalátoru Inno Setup
Deset let vývoje se velmi pozitivně podepsalo na tomto produktu, který v současné verzi 5.2.3 je schopný konkurovat i takovým gigantům jako je InstallShield. Jeho síla spočívá v jednoduchosti, spolehlivé kompatibilitě se všemi systémy Windows počínaje verzí 95 a obrovským možnostem rozšíření funkčnosti pomocí PascalScriptu (včetně možnosti vytvoření vlastních stránek v instalačním průvodci či přizpůsobení existujících stránek).
Inno Setup je v podstatě velmi jednoduchý editor instalačního skriptu se zvýrazňováním syntaxe, kompilátor instalačního skriptu a jednoduchý, avšak plně dostačující debugger. Součástí je také kompletní nápověda a ukázkové skripty. S touto zdarma dostupnou (i pro komerční účely) výbavičkou jste schopni vytvářet velmi profesionální, vícejazyčné instalátory na úrovni.
Komunita kolem Inno Setupu je obrovská, proto vznikají i další nástroje pro usnadnění práce, například ISTool, který umožňuje instalátor vytvořit vizuálně naklikáním vlastností (automaticky vytváří skript), nebo naprosto nedocenitelný Inno Setup Forms Designer (který se už bohužel nevyvíjí a jeho autor zmizel beze stopy), pro vizuální tvorbu vlastních stránek v průvodci instalací.
Pokud tedy hodláte číst dále, prvním krokem je stažení a nainstalování aktuální verze.
Teorie instalačního skriptu
Instalační skript je předpis, podle kterého kompilátor Inno Setupu vytvoří výsledný instalátor. Je to textový soubor, který svou strukturou připomíná INI soubor. Instalační skript NENÍ Case-sensitive, tj. nerozlišuje velká a malá písmena (stejně jako Visual Basic). Skript je rozdělen na tzv. sekce (stejně jako INI soubory), které oddělují různé kategorie nastavení instalátoru. Sekce jsou identifikovány názvem v hranatých závorkách, např. [Files]. Každá sekce obsahuje položky (název=hodnota), nebo parametry (název: “hodnota”) oddělené středníkem. Hodnoty parametrů jsou v úvozovkách, pro použití úvozovek přímo v hodnotě parametru je třeba úvozovky zdvojit (stejně jako ve Visual Basicu).
Sekce | Význam |
[Setup] | Globální nastavení celého instalátoru. Nastavení vzhledu, chování, komprese, omezení… |
[Types] | Definice typů instalace. Běžně známé typy instalace jsou Úplná, Minimální, Vlastní. Lze však definovat i svoje vlastní. |
[Components] | Definice součástí instalace. Zde bych uvedl jako příklad instalaci Microsoft Office, kde lze vybírat jednotlivé součásti pro Word, Excel atd. a jejich podsoučásti. Komponenty mohou být přiřazeny jednotlivým typům. |
[Tasks] | Definice úloh, které lze volitelně provést po instalaci. Může to být například zobrazení souboru, spuštění aplikace, nebo přidání vyjímky do Brány firewall u síťové aplikace. |
[Dirs] | Dodatečné složky, které má instalátor vytvořit. |
[Files] | Všechny soubory, které mají být součástí instalace. Soubory mohou být přiřazeny jednotlivým komponentám. |
[Icons] | Ikony které má instalátor vytvořit. Mohou být v nabídce Start, na pracovní ploše, nebo v panelu Snadné spuštění. Ikony lze vytvářet buď pro všechny uživatele, nebo jen pro aktuálního uživatele. |
[INI] | Zde je možné modifikovat inicializační textové soubory, které se velmi dávno používaly ke konfiguraci aplikací. |
[InstallDelete] | Soubory, které mají být smazány v prvním kroku instalace. Může se jednat například o konfigurační soubory, ale k tomu se většinou používá jiná metodika (v sekci Files). |
[Languages] | Definice jazyků, které bude podporovat instalátor. Inno Setup standardně podporuje 20 světových jazyků včetně češtiny, další jazyky lze stáhnout nebo vytvořit dodatečně. U komerčních instalátorů většinou musíte za jazykové balíčky tvrdě platit. |
[Messages] | Zde je možné “přerazit” výchozí zprávy instalátoru definované v souborech *.isl |
[CustomMessages] | Vlastní zprávy lokalizované do požadovaných jazyků. Používá se v kombinaci se sekcí Languages a parametrem {cm:MessageName}. |
[LangOptions] | Možnosti zobrazení instalátoru (písmo, velikost, kódová stránka) pro různé jazyky. |
[Registry] | Vytváření, úpravy, odstraňování a nastavování oprávnění pro větve a klíče v registru. |
[Run] | Definuje co se má spustit po úspěšném nainstalování aplikace. Lze to spustit buď automaticky nebo po zaškrtnutí volby uživatelem. |
[UninstallDelete] | Stejné jako InstallDelete, ale pro odinstalaci. |
[UninstallRun] | Stejné jako Run, ale pro odinstalaci. |
V instalačním skriptu lze používat konstanty, což jsou zkratky ve složených závorkách, za které kompilátor Inno Setupu dosazuje určité hodnoty (tedy spíše by se hodilo pojmenování proměnné). Konstanty se používají v parametrech. V následující tabulce je uveden seznam nejběžněji používaných konstant, popisovat zde všechny by bylo nošením dříví do lesa (v nápovědě Inno Setupu jsou skvěle zdokumentovány).
Konstanta | Význam |
{app} | Cílová složka pro instalaci aplikace vybraná uživatelem |
{src} | Zdrojová složka ve které se nachází instalátor |
{group} | Programová skupina vybraná uživatelem |
{commondesktop} | Pracovní plocha společná pro všechny uživatele |
{cm:MessageName} | Vlastní lokalizovaná zpráva |
Instalační skript dále může obsahovat společné parametry, které lze používat používat ve všech sekcích, které obsahují parametry oddělené středníky.
Společný parametr | Význam |
Languages | Provede se pro uvedené jazyky |
MinVersion | Provede se pro systém se stejnou nebo vyšší verzí než uvedené verze |
OnlyBelowVersion | Provede se pro systém s nižší verzí než uvedené verze |
Components | Přiřazuje položku uvedeným součástem |
Tasks | Přiřazuje položku uvedeným úlohám |
Praktická ukázka včetně specifikace požadavků na instalátor
Firma AB právě dokončila vývoj aplikace App. Jedná se o první verzi aplikace (1.0.0), která bude distribuována zákazníkům na instalačním médiu (CD). Aby byla aplikace profesionální a zákazník měl s rozchozením aplikace co nejmenší starosti, management firmy požaduje vytvoření instalátoru. Vývojové oddělení firmy ve spolupráci s managementem, který specifikoval požadavky pro instalátor, se dohodlo na následujícím řešení:
- Aplikace je postavena na platformě Microsoft .NET Framework 3.5. Instalátor musí zjistit, zda-li je Framework přítomen a pokud není, nedovolí pokračovat v instalaci. Minimální verze operačního systému byla stanovena na Windows XP Service Pack 3.
- Aplikace je lokalizována do češtiny a angličtiny včetně nápovědy. Uživatelské rozhraní instalátoru, všechna hlášení a položky vytvořené v nabídce Start musí být plně lokalizovány do obou jazyků. Bylo by dobré, aby se instalovaly pouze soubory pro vybranou jazykovou verzi. Soubor se změnami verzí lokalizován být nemusí.
- Instalátor musí bez problémů umět aktualizovat aplikaci, pokud byla nalezena starší verze.
- Aplikaci musí být možné odinstalovat a to standardním postupem z Ovládacích panelů (Přidat nebo odebrat programy).
- Datové soubory aplikace nikdy nesmí být přepsány a musí zůstat na cílovém počítači i po odinstalování aplikace.
- Aplikace používá také vlastní datové soubory (*.app), tyto musí být asociovány s aplikací.
- Název programové složky v nabídce Start je dán napevno, lze zvolit pouze instalaci pro všechny uživatele nebo pouze pro aktuálního uživatele.
- Instalovat aplikaci mohou pouze členové skupiny Administrators.
- Pokud je aplikace spuštěna, nelze provést instalaci nebo odinstalaci.
- Při instalaci by měla být možnost výběru instalovaných součástí.
Poznámka: Firma i název aplikace jsou smyšlené, pokud chcete skutečně otestovat funkčnost instalátoru, vytvořte následující soubory ve složce s instalačním skriptem (můžete použít libovolné soubory s uvedeným názvem, soubor aplikace by měl být spustitelný soubor):
App.exe, App.cs.chm, App.en.chm, Database\AppData.sdf, WhatsNew.txt
[Setup]
;Název aplikace
AppName=App
;Název aplikace včetně verze
AppVerName=App 1.0.0
;Výchozí složka pro instalaci aplikace, {pf}=umístění složky Program Files
DefaultDirName={pf}\App
;Zakázat zobrazení stránky s výběrem složky v nabídce Start,
;protože zástupci budou automaticky vytvořeni buď pro všechny uživatele,
;nebo pouze pro aktuálního uživatele. Tuto možnost stránka s výběrem složky
;v nabídce Start nijak jednoduše neumožňuje, je tam zobrazen seznam, ve kterém
;jsou sloučeny položky pro všechny uživatele s položkami pouze aktuálního uživatele.
DisableProgramGroupPage=yes
;Identifikátor aplikace (Mutex). Pokud je nalezen v paměti, instalátor nedovolí
;pokračovat v instalaci nebo odinstalaci. Tento Mutex musí nastavovat sama aplikace
;při spuštění a při ukončení je nutné ho zase uvolnit!
AppMutex=App100
;Minimální verze operačního systému, na který půjde aplikace nainstalovat (zde Windows XP Service Pack 3).
MinVersion=5.01.2600sp3
;Pokud je vytvořena asociace souborů s vaší aplikací (v registru), nastavením tohoto parametru
;na yes bude instalátor informovat operační systém o změně asociací a změny se hned projeví v systému
;(v opačném případě až po restartu systému).
ChangesAssociations=yes
[Languages]
;Nastavení jazyků podporovaných instalátorem. Jazyk použitý všude v instalátoru je vybrán
;uživatelem při spuštění instalace.
Name: "cs"; MessagesFile: "compiler:Languages\Czech.isl"
Name: "en"; MessagesFile: "compiler:Default.isl"
[Types]
;Definice typů instalace. Parametr iscustom určuje uživatelsky definovanou instalaci.
Name: "Full"; Description: "{cm:Full}"
Name: "Minimal"; Description: "{cm:Minimal}"
Name: "Custom"; Description: "{cm:Custom}"; Flags: iscustom
[Components]
;Definice součástí a jejich přiřazení k určitým typům instalace. Součást Application
;se bude instalovat vždy, nebude možné ji odškrtnout (parametr fixed).
;Součásti s lomítkem tvoří podkategorii příslušné součásti.
Name: "Application"; Description: "{cm:Application}"; Flags: fixed checkablealone; Types: Full Minimal Custom
Name: "Application\Help"; Description: "{cm:Help}"; Types: Full Custom
Name: "Application\Database"; Description: "{cm:Database}"; Types: Full Custom
[Tasks]
;Definice úloh, které budou volitelně provedeny v závěrečném kroku instalace.
;Z úloh označených parametrem exclusive lze vybrat pouze jednu.
Name: "AllUsersShortcuts"; Description: "{cm:AllUsersShortcuts}"; Flags: exclusive
Name: "CurrentUserShortcuts"; Description: "{cm:CurrentUserShortcuts}"; Flags: exclusive unchecked
Name: "RunApplication"; Description: {cm:RunApplication}
[Files]
;Soubory aplikace. Vše co není označeno parametrem external bude zkompilováno přímo
;do instalátoru (setup.exe). Parametr Components určuje do jaké součásti soubor patří,
;Languages určuje jazyk, pro který se bude soubor instalovat (je-li na začátku vybrána Čeština,
;bude se instalovat pouze česká nápověda, je-li vybrána angličtina, potom pouze anglická).
;Parametr onlyifdoesntexist nainstaluje soubor pouze pokud neexistuje v cílové složce,
;uninsneveruninstall označuje, že soubor nemá být odstraněn v rámci odinstalování.
Source: "{src}\App.exe"; DestDir: "{app}"; Components: Application
Source: "{src}\App.cs.chm"; DestDir: "{app}\Docs"; Components: Application\Help; Languages: cs
Source: "{src}\App.en.chm"; DestDir: "{app}\Docs"; Components: Application\Help; Languages: en
Source: "{src}\Database\AppData.sdf"; DestDir: "{commonappdata}\App"; Components: Application\Database; Flags: onlyifdoesntexist uninsneveruninstall
Source: "{src}\WhatsNew.txt"; DestDir: "{app}\Docs"; Components: Application; Flags: external isreadme
[Registry]
;Vytváření větví, klíčů a hodnot v registru. Tyto čtyři řádky zajišťují asociaci souborů
;*.app s aplikací. Pokud provádíte asociaci souborů s aplikací, nezapomeňte na položku
;ChangesAssociations=yes v sekci [Setup].
Root: HKCR; Subkey: ".app"; ValueType: string; ValueName: ""; ValueData: "AppFile"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "AppFile"; ValueType: string; ValueName: ""; ValueData: "{cm:FileType}"; Flags: uninsdeletekey
Root: HKCR; Subkey: "AppFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\App.exe,0"
Root: HKCR; Subkey: "AppFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\App.exe"" ""%1"""
[Icons]
;Všimněte si provázání položek s úlohami ([Tasks]) AllUsersShortcuts a CurrentUserShortcuts.
;Provede se buď vytvoření zástupců v nabídce Start pro všechny uživatele,
Name: "{commonprograms}\App\{cm:Application}"; Filename: "{app}\App.exe"; Tasks: AllUsersShortcuts
Name: "{commonprograms}\App\{cm:Help}"; Filename: "{app}\App.cs.chm"; Tasks: AllUsersShortcuts; Languages: cs
Name: "{commonprograms}\App\{cm:Help}"; Filename: "{app}\App.en.chm"; Tasks: AllUsersShortcuts; Languages: en
;nebo vytvoření zástupců v nabídce Start pouze pro aktuálního uživatele,
Name: "{userprograms}\App\{cm:Application}"; Filename: "{app}\App.exe"; Tasks: CurrentUserShortcuts
Name: "{userprograms}\App\{cm:Help}"; Filename: "{app}\App.cs.chm"; Tasks: CurrentUserShortcuts; Languages: cs
Name: "{userprograms}\App\{cm:Help}"; Filename: "{app}\App.en.chm"; Tasks: CurrentUserShortcuts; Languages: en
;podle toho co vybere uživatel při instalaci.
[Run]
;Zde je uvedeno, co má být spuštěno po dokončení instalace. Volitelné spuštění aplikace
;je rovněž provázáno s určitou úlohou (RunApplication).
Filename: "{app}\App.exe"; Tasks: RunApplication
[CustomMessages]
;Definice všech vlastních zpráv instalátoru ve všech podporovaných jazycích.
;Podporované jazyky jsou definovány v sekci [Languages], zde je zápis
;položek ve formátu NázevJazyku.Položka=Zpráva
;Konstanta %n znamená nový řádek (vbCrLf ve VB.NET).
cs.Application=App
cs.Help=Nápověda
cs.Database=Databázové soubory
cs.RunApplication=&Spustit aplikaci App
cs.Full=Kompletní
cs.Minimal=Minimální
cs.Custom=Vlastní
cs.FileType=Soubor aplikace App
cs.AllUsersShortcuts=Instalovat pro &všechny uživatele
cs.CurrentUserShortcuts=Instalovat pouze pro &aktuálního uživatele
cs.DotNetFxNotFound=Nebyla nalezena platforma Microsoft .NET Framework 3.5.%nNainstalujte prosím ručně tuto součást a spusťte instalátor znovu.
en.Application=App
en.Help=Help
en.Database=Database files
en.RunApplication=&Run App
en.Full=Full
en.Minimal=Minimal
en.Custom=Custom
en.FileType=App application's file
en.AllUsersShortcuts=Install for &all users
en.CurrentUserShortcuts=Install for ¤t user only
en.DotNetFxNotFound=Microsoft .NET Framework 3.5 platform was not found.%nPlease install this component manually and run installer again.
;V následující sekci je zapsán vlastní rozšiřující kód pro instalátor (PascalScript).
;V tomto případě se jedná o detekci .NET Frameworku 3.5.
[Code]
//Tato pevně definovaná funkce je volána při inicializaci instalátoru.
function InitializeSetup(): Boolean;
//Definice proměnných. Proměnné nelze definovat kdekoliv v kódu, je to nutné vždy na začátku.
var
Data: Cardinal;
Success: Boolean;
begin
//Dotaz na hodnotu klíče v registru.
Success := RegQueryDWordValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5', 'Install', Data);
//Porovnání získaných hodnot.
if ((not Success) or (Data <> 1)) then
begin
//Zobrazení dialogového okna se zprávou o chybějícím .NET Frameworku.
//Zpráva je načtena z položky definované v [CustomMessages].
MsgBox(CustomMessage('DotNetFxNotFound'), mbError, MB_OK);
//Vynucené ukončení instalace.
Abort();
end;
end;
//Pro lepší porozumění PascalScriptu uvádím ekvivalentní VB.NET kód:
//Function InitializeSetup() As Boolean
// Dim Data As Long
// Dim Success As Boolean
// Try
// Data = CLng(Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5", "Install", 0))
// Success = True
// Catch
// End Try
// If ((Not Success) OrElse (Data <> 1)) Then
// MessageBox.Show(String.Format("Nebyla nalezena platforma Microsoft .NET Framework 3.5.{0}Nainstalujte prosím ručně tuto součást a spusťte instalátor znovu.", vbCrLf), Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
// End
// End If
//End Function