added start menu icons to start/stop service

[Setup]
#include "setup.iss"
OutputBaseFilename=unimrcp-0.2.0

[Types]
Name: "full"; Description: "Full installation"
Name: "server"; Description: "Server installation"
Name: "client"; Description: "Client installation"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "server"; Description: "UniMRCP server"; Types: full server
Name: "server\cepstral"; Description: "Cepstral synthesizer plugin"; Types: full server
Name: "server\demosynth"; Description: "Demo synthesizer plugin"; Types: full server
Name: "server\demorecog"; Description: "Demo recognizer plugin"; Types: full server
Name: "client"; Description: "UniMRCP client (demo application)"; Types: full client

[Files]
Source: "..\..\Release\bin\unimrcpserver.exe"; DestDir: "{app}\bin"; Components: server
Source: "..\..\Release\bin\unimrcpservice.exe"; DestDir: "{app}\bin"; Components: server
Source: "..\..\Release\bin\unimrcpclient.exe"; DestDir: "{app}\bin"; Components: client
Source: "..\..\Release\bin\*.dll"; DestDir: "{app}\bin"; Components: server client
Source: "..\..\Release\plugin\mrcpcepstral.dll"; DestDir: "{app}\plugin"; Components: server/cepstral
Source: "..\..\Release\plugin\demosynth.dll"; DestDir: "{app}\plugin"; Components: server/demosynth
Source: "..\..\Release\plugin\demorecog.dll"; DestDir: "{app}\plugin"; Components: server/demorecog
Source: "..\..\Release\conf\unimrcpserver.xml"; DestDir: "{app}\conf"; Components: server
Source: "..\..\Release\conf\unimrcpclient.xml"; DestDir: "{app}\conf"; Components: client

[Icons]
Name: "{group}\UniMRCP Server Console"; Filename: "{app}\bin\unimrcpserver.exe"; Parameters: "-c ""{app}\conf"" -p ""{app}\plugin"""; Components: server
Name: "{group}\UniMRCP Client Console"; Filename: "{app}\bin\unimrcpclient.exe"; Parameters: "-c ""{app}\conf"""; Components: client
Name: "{group}\UniMRCP Service\Start Server"; Filename: "{app}\bin\unimrcpservice.exe"; Parameters: "--start"; Components: server
Name: "{group}\UniMRCP Service\Stop Server"; Filename: "{app}\bin\unimrcpservice.exe"; Parameters: "--stop"; Components: server
Name: "{group}\Uninstall"; Filename: "{uninstallexe}"

[Run]
Filename: "{app}\bin\unimrcpservice.exe"; Description: "Register service"; Parameters: "--register ""{app}\bin\unimrcpserver.exe --service"""; Components: server

[UninstallRun]
Filename: "{app}\bin\unimrcpservice.exe"; Parameters: "--unregister"; Components: server

[Code]
var
  Content: String;

procedure ModifyPluginConf(PluginName: String; Enable: Boolean);
var
  TextFrom: String;
  TextTo: String;
begin
  if Enable = True then
  begin
    TextFrom := 'class="' + PluginName + '" enable="0"';
    TextTo := 'class="' + PluginName + '" enable="1"';
  end
  else
  begin
    TextFrom := 'class="' + PluginName + '" enable="1"';
    TextTo := 'class="' + PluginName + '" enable="0"';
  end
  StringChange (Content, TextFrom, TextTo);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  CfgFile: String;
begin
  if CurStep = ssPostInstall then
  begin
    CfgFile := ExpandConstant('{app}\conf\unimrcpserver.xml');
    LoadStringFromFile (CfgFile, Content);
    ModifyPluginConf ('mrcpcepstral', IsComponentSelected('server\cepstral'));
    ModifyPluginConf ('demosynth', IsComponentSelected('server\demosynth'));
    ModifyPluginConf ('demorecog', IsComponentSelected('server\demorecog'));
    SaveStringToFile (CfgFile, Content, False);
  end
end;

[Setup]
#include "setup.iss"
OutputBaseFilename=unimrcp-0.2.0

[Types]
Name: "full"; Description: "Full installation"
Name: "server"; Description: "Server installation"
Name: "client"; Description: "Client installation"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "server"; Description: "UniMRCP server"; Types: full server
Name: "server\cepstral"; Description: "Cepstral synthesizer plugin"; Types: full server
Name: "server\demosynth"; Description: "Demo synthesizer plugin"; Types: full server
Name: "server\demorecog"; Description: "Demo recognizer plugin"; Types: full server
Name: "client"; Description: "UniMRCP client (demo application)"; Types: full client

[Files]
Source: "..\..\Release\bin\unimrcpserver.exe"; DestDir: "{app}\bin"; Components: server
Source: "..\..\Release\bin\unimrcpclient.exe"; DestDir: "{app}\bin"; Components: client
Source: "..\..\Release\bin\*.dll"; DestDir: "{app}\bin"; Components: server client
Source: "..\..\Release\plugin\mrcpcepstral.dll"; DestDir: "{app}\plugin"; Components: server/cepstral
Source: "..\..\Release\plugin\demosynth.dll"; DestDir: "{app}\plugin"; Components: server/demosynth
Source: "..\..\Release\plugin\demorecog.dll"; DestDir: "{app}\plugin"; Components: server/demorecog
Source: "..\..\Release\conf\unimrcpserver.xml"; DestDir: "{app}\conf"; Components: server
Source: "..\..\Release\conf\unimrcpclient.xml"; DestDir: "{app}\conf"; Components: client

[Icons]
Name: "{group}\UniMRCP Server"; Filename: "{app}\bin\unimrcpserver.exe"; Parameters: "-c ""{app}\conf"" -p ""{app}\plugin"""; Components: server
Name: "{group}\UniMRCP Client"; Filename: "{app}\bin\unimrcpclient.exe"; Parameters: "-c ""{app}\conf"""; Components: client
Name: "{group}\Uninstall"; Filename: "{uninstallexe}"

[Run]
Filename: "{app}\bin\unimrcpserver.exe"; Description: "Register service"; Parameters: "--register"; Components: server

[UninstallRun]
Filename: "{app}\bin\unimrcpserver.exe"; Parameters: "--unregister"; Components: server

[Code]
var
  Content: String;

procedure ModifyPluginConf(PluginName: String; Enable: Boolean);
var
  TextFrom: String;
  TextTo: String;
begin
  if Enable = True then
  begin
    TextFrom := 'class="' + PluginName + '" enable="0"';
    TextTo := 'class="' + PluginName + '" enable="1"';
  end
  else
  begin
    TextFrom := 'class="' + PluginName + '" enable="1"';
    TextTo := 'class="' + PluginName + '" enable="0"';
  end
  StringChange (Content, TextFrom, TextTo);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  CfgFile: String;
begin
  if CurStep = ssPostInstall then
  begin
    CfgFile := ExpandConstant('{app}\conf\unimrcpserver.xml');
    LoadStringFromFile (CfgFile, Content);
    ModifyPluginConf ('mrcpcepstral', IsComponentSelected('server\cepstral'));
    ModifyPluginConf ('demosynth', IsComponentSelected('server\demosynth'));
    ModifyPluginConf ('demorecog', IsComponentSelected('server\demorecog'));
    SaveStringToFile (CfgFile, Content, False);
  end
end;


Add Dutch translation for new string in the Installer

;Defaults (English)
CreateStartShortcut=Create a Start Menu shortcut
NoKaM=The installation wizard detected that you do not have Knights and Merchants: The Peasants Rebellion installed. You must have the original game installed in order to play the KaM Remake.%n%nThe installation will be aborted.
SteamFirstRun=Original KaM installed from Steam needs to be started at least once on the system, in order for KMR installer to be able to detect and verify it.
CantUpdate=The installation wizard was unable to find an existing version of the KaM Remake to be updated. Please download and install the complete installer instead.%n%nThe installation will be aborted.
OpenAL=Do you want the installation wizard to install OpenAL? (Strongly recommended) It is required for sounds to work in the KaM Remake
ViewReadme=View the Readme
DeleteSaves=Do you want to delete all your saved games and the progress of all campaigns as well?
DeleteMaps=Do you want to delete all Maps and Campaigns as well?

;Dutch
dut.CreateStartShortcut=Aanmaken van een start menu snelkoppeling
dut.NoKaM=De installatie wizard heft gedetecteerd dat Knights and Merchants: Te Peasants Rebellion niet is geinstalleerd.%n%nDe installatie is afgebroken
dut.SteamFirstRun=Originele KaM geïnstalleerd vanaf Steam moet minstens één keer worden gestart op deze computer, zodat het KMR-installatieprogramma het spel kan detecteren en verifiëren.
dut.CantUpdate=De installatie wizard kon geen bestaande versie vinden van de KaM Remake om deze bij te werken naar de nieuwste versie. Download en installeer de complete versie.%n%nDe installatie is afgebroken
dut.OpenAL=Wil je dat de installatie wizard OpenAL installeerd? (Aan te raden) OpenAL is nodig voor de werking van het geluid in KaM Remake
dut.ViewReadme=Lees de Readme
dut.DeleteSaves=Wil je ook alle opgeslagen spellen en voortgang in de campagnes verwijderen?
dut.DeleteMaps=Wil je ook alle Kaarten en Campagnes verwijderen?

;Swedish
swe.CreateStartShortcut=Skapa en genväg i startmenyn
swe.NoKaM=Det verkar som att du inte har Knights and Merchants: The Peasants Rebellion installerat på din dator.%n%nInstallationen kommer att avbrytas.
swe.CantUpdate=Kunde inte hitta en redan installerad version av KaM Remake att uppdatera. Ladda ner och installera den kompletta versionen istället.%n%nInstallationen kommer att avbrytas.
swe.OpenAL=Vill du även installera OpenAL? (Rekommenderas starkt) Det krävs för att ljud ska fungera i KaM Remake
swe.ViewReadme=Visa Readme-filen

;German
ger.CreateStartShortcut=Verknüpfung im Startmenü erstellen
ger.NoKaM=Setup hat ermittelt, dass Knights and Merchants: The Peasants Rebellion nicht installiert ist.
ger.CantUpdate=Setup war nicht in der Lage eine installierte Version von KaM Remake zu aktualisieren. Bitte lade die Vollversion von KaM Remake herunter und führe das Setup erneut aus.
ger.OpenAL=Soll Setup auch OpenAl installieren (empfohlen)? Es wird für die Soundwiedergabe von KaM Remake benötigt.
ger.ViewReadme=Readme anzeigen

;Polish
pol.CreateStartShortcut=Stwórz skrót w Menu Start
pol.NoKaM=Kreator instalacji wykrył że nie masz zainstalowanego Knights and Merchants: The Peasants Rebellion.%n%nInstalacja zostanie przerwana.
pol.CantUpdate=Kreator instalacji nie był w stanie znaleźć istniejącej wersji KaM Remake do zaktualizowania. Proszę pobrać i zainstalować kompletny instalator.%n%nInstalacja zostanie przerwana.
pol.OpenAL=Czy chcesz aby kreator instalacji zainstalował OpenAL? (Zalecane) Jest on wymagany by działały dźwięki w KaM Remake.
pol.ViewReadme=Zobacz plik Readme

;Hungarian
hun.CreateStartShortcut=Start Menü ikon létrehozása
hun.NoKaM=A telepítő nem észlelte a Knights and Merchants: A Parasztfelkelést telepítve.%n%nA telepítés megszakításra kerül.
hun.CantUpdate=A telepítő nem talált KaM Remake verziót a számítógépen, hogy frissítse. Kérem töltse le és használja a teljes telepítőt.%n%nA telepítés megszakításra kerül.
hun.OpenAL=Szeretnéd, hogy a telepítő telepítse az OpenAL-t? (Erősen ajánlott) A hangok működéséhez szükséges a KaM Remake-ben
hun.ViewReadme=Olvass el fájl megtekintése

;French
fre.CreateStartShortcut=Créer un raccourci dans le menu Démarrer
fre.NoKaM=L'assistant d'installation n'a détecté aucune installation de Knights and Merchants : The Peasants Rebellion.%n%nL'installation sera interrompue.
fre.CantUpdate=L'assistant d'installation n'a détecté aucune version existante de KaM Remake à mettre à jour. Veuillez télécharger et utiliser l'installateur complet.%n%nL'installation sera interrompue.
fre.OpenAL=Voulez-vous que l'assistant d'installation installe OpenAL ? (fortement recommandé) OpenAL est requis pour le fonctionnement audio de KaM Remake.
fre.ViewReadme=Voir le lisez-moi

;Czech
cze.CreateStartShortcut=Vytvořit zástupce v nabídce Start
cze.NoKaM=Instalátor zjistil, že hra Knights and Merchants: The Peasants Rebellion není nainstalována. Instalace bude nyní ukončena.
cze.SteamFirstRun=Knights and Merchants na Steamu je potřeba pustit alespoň jednou, aby mohla instalace pokračovat.
cze.CantUpdate=Instalátor nenalezl na vašem počítači KaM Remake. Nejprve si stáhněte kompletní KaM Remake, poté můžete aktualizovat. Instalace bude nyní ukončena.
cze.OpenAL=Chcete nainstalovat OpenAL? (Doporučeno) OpenAL je vyžadováno pro správnou funkci zvuku v KaM Remake
cze.ViewReadme=Otevřít Readme
cze.DeleteSaves=Chcete také smazat všechny uložené hry a postup v kampani?
cze.DeleteMaps=Chcete také smazat všechny mapy a kampaně?

;Russian
rus.CreateStartShortcut=Создать ярлык в меню Пуск
rus.NoKaM=Мастер установки не обнаружил установленной игры Knights and Merchants: The Peasants Rebellion. Оригинальная игра необходима для установки КаМ Ремейк.%n%nУстановка будет отменена.
rus.SteamFirstRun=Оригинальная игра, установленная из Steam должна быть запущена хотя бы 1 раз, чтобы данный установщик КаМ Ремейк смог ее обнаружить и проверить.
rus.CantUpdate=Мастер установки не смог обнаружить версию КаМ Ремейк для обновления. Пожалуйста скачайте и запустите полную версию установщика.%n%nУстановка будет отменена.
rus.OpenAL=Установить OpenAL? (рекоммендуется) Необходимо для работы звука в КаМ Ремейк
rus.ViewReadme=Показать Readme
rus.DeleteSaves=Вы хотите также удалить все сохраненные игры и прогресс всех кампаний?
rus.DeleteMaps=Вы хотите также удалить все карты и кампании?

;Brazilian Portuguese
ptb.CreateStartShortcut=Criar um atalho no menu Iniciar
ptb.NoKaM=O assistente de instalação detectou que você não tem Knights and Merchants: The Peasants Rebellion instalado.%n%nA instalação será abortada.
ptb.CantUpdate=O assistente de instalação foi incapaz de encontrar uma versão existente do KaM Remake para atualizar. Por favor, baixe e instale através do instalador completo.%n%nA instalação será abortada.
ptb.OpenAL=Você deseja que o assistente de instalação instale o OpenAL? (Altamente recomendado) É necessário para o funcionamento dos sons no KaM Remake
ptb.ViewReadme=Ver o Readme

;Italian
ita.CreateStartShortcut=Crea collegamento nel Menu Avvio
ita.NoKaM=La procedura guidata di installazione non ha rilevato alcuna copia di "Knights and Merchants: The Peasants Rebellion". È necessaria l'installazione del gioco originale per poter utilizzare "KaM Remake".%n%nLa procedura di installazione verrà ora annullata.
ita.CantUpdate=La procedura guidata di installazione non ha rilevato alcuna versione di "KaM Remake" da aggiornare. Si prega di scaricare e utilizzare invece il programma di installazione completo.%n%nLa procedura di installazione verrà ora annullata.
ita.OpenAL=Vuoi procedere all'installazione di OpenAL? (Fortemente raccomandata) È necessaria per il corretto funzionamento dell'audio in "KaM Remake"
ita.ViewReadme=Visualizza il file Readme

;Spanish
spa.CreateStartShortcut=Crea un acceso directo en el menú de inicio
spa.NoKaM=El asistente de instalación ha detectado que no tienes Knights and Merchants: The Peasants Rebellion instalado. Usted debe tener instalado el juego original para poder jugar el remake de Kam.%n%nLa instalación se interrumpirá
spa.CantUpdate=El asistente de instalación no ha podido encontrar la versión Kam Remake para poder actualizar. Por favor, descarga y instala la versión completa.%n%nLa instalación se interrumpirá.
spa.OpenAL=¿Quieres que el asistente de instalación instale OpenAL? (Muy recomendable) se requiere para el sonido del juego Kam Remake
spa.ViewReadme=Ver el archivo Readme

;Bulgarian
bul.CreateStartShortcut=Създай пряк път
bul.NoKaM=Инсталацията откри, че нямате инсталирана Knights and Merchants: The Peasants Rebellion. Вие трябва да имате Knights and Merchants: The Peasants Rebellion, за да играете KaM Remake.%n%nИнсталацията се прекратява.
bul.CantUpdate=Инсталацията не успя да намери съществуваща версия на KaM Remake, за да бъде подобрена. Моля изтеглете и инсталирайте пълния инсталатор.%n%nИнсталацията ще се прекрати.
bul.OpenAL=Искате ли инсталацията да инсталира OpenAL? (Силно се препоръчва) Нужно е, за да работи звука в играта.
bul.ViewReadme=Виж "Прочети ме"

;Estonian
est.CreateStartShortcut=Loo start menüü otsetee
est.NoKaM=Paigaldamise programm on avastanud, et Teil ei ole paigaldatud Knights and Merchants: The Peasants Rebellion. Teil peab olema paigaldatud originaal mäng, et mängida mängu KaM Remake.%n%nPaigaldamine katkestakase.
est.CantUpdate=Paigaldamise programm ei leidnud olemas olevat KaM Remake versiooni, mida uuendada. Palun laadige internetist alla täis versioon mängust KaM Remake.%n%nPaigaldamine katkestatakse.
est.OpenAL=Kas te soovite paigaldada programmi OpenAL? (Tungivalt soovitatav) See on vajalik, et helid töötaksid mängus KaM Remake.
est.ViewReadme=Vaadake faili Readme

;Slovak
svk.CreateStartShortcut=Vytvoriť zástupcu v ponuke Štart
svk.NoKaM=Sprievodca inštaláciou zistil, že nemáte nainštalovaný Knight & Merchants: The Peasants Rebellion. Musíte mať nainštalovanú originálnu hru, aby ste mohli hrať KaM Remake.%n%nInštalácia bude prerušená.
svk.CantUpdate=Sprievodca inštaláciou nemohol nájsť existujúcu verziu KaM Remake, je ju potrebné aktualizovať. Prosím, stiahnite a nainštalujte kompletnú inštaláciu.%n%nInštalácia bude prerušená.
svk.OpenAL=Chcete použiť spriveodcu na inštaláciu OpenAL? (Dôrazne odporúčané). Je to potrebné pre zvuky v hre v KAM Remake.
svk.ViewReadme=Pozri súbor Readme

;Romanian
rom.CreateStartShortcut=Creează o scurtătura în meniul de Start
rom.NoKaM=Instalarea a detectat ca nu ai instalat Knights and Merchants: The Peasants Rebellion. Trebuie să ai instalat jocul original pentru a putea juca KaM Remake.%n%nInstalarea se va întrerupe.
rom.CantUpdate=Instalarea nu a putut găsi o versiune care va putea fi updată. Te rog să downloadezi fisierul de instalare complet.%n%nInstalarea se va întrerupe.
rom.OpenAL=Vrei să instalezi OpenAL?(Recomandat) Este necesar pentru sunetele din KaM Remake
rom.ViewReadme=Vizualizeazp fisierul Citeste-ma

;Ukrainian
ukr.CreateStartShortcut=Створити ярлик стартового меню
ukr.NoKaM=Майстер встановлення программи не знайшов оригіналу Knights and Merchants: The Peasants Rebellion на вашому комп`ютері. Ви маєте встановити оригінал для того , щоб грат в KaM Remake.%n%nІнсталяцію скасовано.
ukr.CantUpdate=Майстер встановлення програми не зміг знайти KaM Remake на компютері для того, щоб оновити його. Будь ласка , в першу чергу , завантажте і встановіть повну версію перш ніж встановлювати апдейт.%n%nІнсталяцію скасовано.
ukr.OpenAL=Чи хочете ви щоби майстер встановив OpenAL? (Дуже рекомендується) Він необхідний для роботи звуку у KaM Remake
ukr.ViewReadme=Відкрити Readme

;Norwegian
nor.CreateStartShortcut=Legg til snarvei i Start-menyen
nor.NoKaM=Installasjonsveiviseren oppdaget at du ikke har Knights and Merchants: The Peasants Rebellion installert. Du må ha det originale spillet installert for å spille KaM Remake.%n%nInstallasjonen vil bli avbrutt.
nor.CantUpdate=Installasjonen kunne ikke finne en eksisterende versjon av KaM Remake å oppdatere. Vennligst last ned og installer det fullstendige installasjonsprogrammet i stedet.%n%nInstallasjonen vil bli avbrutt.
nor.OpenAL=Ønsker du at installasjonsveiviseren skal installere OpenAL? (Anbefales sterkt) Det er nødvendig for at lyder skal fungere i KaM Remake
nor.ViewReadme=Vis Readme

;Belarusian
bel.CreateStartShortcut=Стварыць цэтлік ў меню "Пуск"
bel.NoKaM=Майстар ўстаноўкі выявіў што ў вас няма ўсталяванай iгры Knights and Merchants: The Peasants Rebellion. Вы павінны ўсталяваць арыгінальную iгру каб іграць ў KaM Remake.%n%nУстаноўка будзе спынена.
bel.CantUpdate=Майстру ўстаноўкі не ўдаецца знайсці версію KaM Remake для абнаўлення. Калі ласка загрузіце поўны пакет ўстаноўкі.%n%nУстаноўка будзе спынена.
bel.OpenAL=Вы хочаце ўсталяваць OpenAL? (настойліва рэкамендуецца) Гэта неабходна для работы гуку ў KaM Remake
bel.ViewReadme=Адкрыць Readme

;Japanese
jpn.CreateStartShortcut=スタートメニューのショートカットが作成されます。
jpn.NoKaM=インストールウィザードが"Knights and Merchants: The Peasants Rebellion"をインストールしていないの検出されました。KAM リメイクがフレーされるにはオリジナルのゲームはインストールしてはいけません。インストールは中止されました。
jpn.CantUpdate=インストールウィザードは既存のKAMリメイクバージョンが見つかりませんでした。その代わりに全部のインストーラはダウンロートしてインストールしてください。インストールは中止されました。
jpn.OpenAL=インストールウィザードがOpenALをインストールしたいですか「強い推奨」。KAM リメイクの音楽などを聞くと必要です。
jpn.ViewReadme=Readmeが表示されます。

;Turkish
tur.CreateStartShortcut=Başlat menüsü kısayolu oluştur.
tur.NoKaM=Kurulum sihirbazı orijinal Knights and Merchants: The Peasants Rebellion oyununun kurulu olmadığını tespit etti. KaM Remake modunu oynayabilmek için orijinal oyuna sahip olmanız gerekmektedir.%n%nKurulum sihirbazı kapanacaktır.
tur.CantUpdate=Kurulum sihirbazı herhangi bir kurulu KaM Remake versiyonu bulamadı. Lütfen complete installer indirerek kurulum yapınız.%n%nKurulum sihirbazı kapanacaktır.
tur.OpenAL=Kurulum sihirbazının OpenAL kurmasını ister misiniz? (Tavsiye edilir) Seslerin oyun içinde çalışması için gereklidir.
tur.ViewReadme=Beni oku dosyasını aç

;Korean
kor.CreateStartShortcut=시작 메뉴 단축 아이콘 만들기
kor.NoKaM=설치 마법사가 '기사와 상인:농민의 반란'이 설치가 안된것으로 확인되었습니다. '기사와 상인 다시만듬'을 실행하기 위해서는 반드시 원본 게임이 설치되어 있어야 합니다. 설치가 중단 됩니다.
kor.CantUpdate=설치 마법사가 갱신할 '기사와 상인 다시만듬'의 기존 버전을 찾을 수 없습니다. 전체 설치 프로그램 대신에 다운로드하여 설치 해주십시오. 설치가 중단 됩니다.
kor.OpenAL=OpenAL을 설치하기위해 설치 마법사가 필요합니까? (강력하게 추천함) '기사와 상인 다시만듬'에서 소리를 작동하는데 필요합니다.
kor.ViewReadme=읽어보기

;Serbian
srb.CreateStartShortcut=Направите Старт Мену Пречицу
srb.NoKaM=Инсталациони чаробњак је приметио да немате Knights and Merchants: The Peasants Rebellion инсталирано.Морате имати оригиналну игру инсталирану да бисте играли KaM Remake.%n%nИнсталације ће престати са радом.
srb.CantUpdate=Инсталациони чаробњак није могао да нађе постојећу верзију KaM Remake да се усавремени.Молимо вас скините и инсталирајте комплетан инсталер уместо тога.%n%nИнсталација ће престати са радом.
srb.OpenAL=Да ли желите да вам инсталациони чаробњакисталира OpenAL? (Врло препоручљиво) Потребно је да бих ѕвукови радили у KaM Remake.
srb.ViewReadme=Прочитајте Реадме

;Chinese
chn.CreateStartShortcut=创建开始菜单快捷方式
chn.NoKaM=安装向导检测到没有《骑士与商人之农民起义》的安装。为了能玩重制版游戏，必须先安装原版游戏。本安装程序将被终止。
chn.CantUpdate=安装向导无法找到一个存在的重制版能够被升级。请重新下载并安装完整的安装包。本安装程序将被终止。
chn.OpenAL=你想用安装向导来安装OpenAL吗？（强烈推荐）这是音效文件运行的必需程序。
chn.ViewReadme=查看自述文件

;Slovenian
slv.CreateStartShortcut=Ustvari bljižnico na meniju
slv.NoKaM=Čarovnik za namestitev je zaznal da nimate nameščeno igro Knights and Merchants: The Peasants Rebellion. Morate imeti nameščeno originalno igro če želite igrati KaM Remake.%n%nNamestitev bo prekinjena
slv.OpenAL=Ali želite namestiti OpenAL? (Močno priporočeno) potrebno je za elovanje zvokov v igri KaM Remake.
slv.ViewReadme=Poglej si opis

;Defaults (English)
CreateStartShortcut=Create a Start Menu shortcut
NoKaM=The installation wizard detected that you do not have Knights and Merchants: The Peasants Rebellion installed. You must have the original game installed in order to play the KaM Remake.%n%nThe installation will be aborted.
SteamFirstRun=Original KaM installed from Steam needs to be started at least once on the system, in order for KMR installer to be able to detect and verify it.
CantUpdate=The installation wizard was unable to find an existing version of the KaM Remake to be updated. Please download and install the complete installer instead.%n%nThe installation will be aborted.
OpenAL=Do you want the installation wizard to install OpenAL? (Strongly recommended) It is required for sounds to work in the KaM Remake
ViewReadme=View the Readme
DeleteSaves=Do you want to delete all your saved games and the progress of all campaigns as well?
DeleteMaps=Do you want to delete all Maps and Campaigns as well?

;Dutch
dut.CreateStartShortcut=Aanmaken van een start menu snelkoppeling
dut.NoKaM=De installatie wizard heft gedetecteerd dat Knights and Merchants: Te Peasants Rebellion niet is geinstalleerd.%n%nDe installatie is afgebroken
dut.CantUpdate=De installatie wizard kon geen bestaande versie vinden van de KaM Remake om deze bij te werken naar de nieuwste versie. Download en installeer de complete versie.%n%nDe installatie is afgebroken
dut.OpenAL=Wil je dat de installatie wizard OpenAL installeerd? (Aan te raden) OpenAL is nodig voor de werking van het geluid in KaM Remake
dut.ViewReadme=Lees de Readme

;Swedish
swe.CreateStartShortcut=Skapa en genväg i startmenyn
swe.NoKaM=Det verkar som att du inte har Knights and Merchants: The Peasants Rebellion installerat på din dator.%n%nInstallationen kommer att avbrytas.
swe.CantUpdate=Kunde inte hitta en redan installerad version av KaM Remake att uppdatera. Ladda ner och installera den kompletta versionen istället.%n%nInstallationen kommer att avbrytas.
swe.OpenAL=Vill du även installera OpenAL? (Rekommenderas starkt) Det krävs för att ljud ska fungera i KaM Remake
swe.ViewReadme=Visa Readme-filen

;German
ger.CreateStartShortcut=Verknüpfung im Startmenü erstellen
ger.NoKaM=Setup hat ermittelt, dass Knights and Merchants: The Peasants Rebellion nicht installiert ist.
ger.CantUpdate=Setup war nicht in der Lage eine installierte Version von KaM Remake zu aktualisieren. Bitte lade die Vollversion von KaM Remake herunter und führe das Setup erneut aus.
ger.OpenAL=Soll Setup auch OpenAl installieren (empfohlen)? Es wird für die Soundwiedergabe von KaM Remake benötigt.
ger.ViewReadme=Readme anzeigen

;Polish
pol.CreateStartShortcut=Stwórz skrót w Menu Start
pol.NoKaM=Kreator instalacji wykrył że nie masz zainstalowanego Knights and Merchants: The Peasants Rebellion.%n%nInstalacja zostanie przerwana.
pol.CantUpdate=Kreator instalacji nie był w stanie znaleźć istniejącej wersji KaM Remake do zaktualizowania. Proszę pobrać i zainstalować kompletny instalator.%n%nInstalacja zostanie przerwana.
pol.OpenAL=Czy chcesz aby kreator instalacji zainstalował OpenAL? (Zalecane) Jest on wymagany by działały dźwięki w KaM Remake.
pol.ViewReadme=Zobacz plik Readme

;Hungarian
hun.CreateStartShortcut=Start Menü ikon létrehozása
hun.NoKaM=A telepítő nem észlelte a Knights and Merchants: A Parasztfelkelést telepítve.%n%nA telepítés megszakításra kerül.
hun.CantUpdate=A telepítő nem talált KaM Remake verziót a számítógépen, hogy frissítse. Kérem töltse le és használja a teljes telepítőt.%n%nA telepítés megszakításra kerül.
hun.OpenAL=Szeretnéd, hogy a telepítő telepítse az OpenAL-t? (Erősen ajánlott) A hangok működéséhez szükséges a KaM Remake-ben
hun.ViewReadme=Olvass el fájl megtekintése

;French
fre.CreateStartShortcut=Créer un raccourci dans le menu Démarrer
fre.NoKaM=L'assistant d'installation n'a détecté aucune installation de Knights and Merchants : The Peasants Rebellion.%n%nL'installation sera interrompue.
fre.CantUpdate=L'assistant d'installation n'a détecté aucune version existante de KaM Remake à mettre à jour. Veuillez télécharger et utiliser l'installateur complet.%n%nL'installation sera interrompue.
fre.OpenAL=Voulez-vous que l'assistant d'installation installe OpenAL ? (fortement recommandé) OpenAL est requis pour le fonctionnement audio de KaM Remake.
fre.ViewReadme=Voir le lisez-moi

;Czech
cze.CreateStartShortcut=Vytvořit zástupce v nabídce Start
cze.NoKaM=Instalátor zjistil, že hra Knights and Merchants: The Peasants Rebellion není nainstalována. Instalace bude nyní ukončena.
cze.CantUpdate=Instalátor nenalezl na vašem počítači KaM Remake. Nejprve si stáhněte kompletní KaM Remake, poté můžete aktualizovat. Instalace bude nyní ukončena.
cze.OpenAL=Chcete nainstalovat OpenAL? (Doporučeno) OpenAL je vyžadováno pro správnou funkci zvuku v KaM Remake
cze.ViewReadme=Otevřít Readme
cze.SteamFirstRun=Knights and Merchants na Steamu je potřeba pustit alespoň jednou, aby mohla instalace pokračovat.
cze.DeleteSaves=Chcete také smazat všechny uložené hry a postup v kampani?
cze.DeleteMaps=Chcete také smazat všechny mapy a kampaně?

;Russian
rus.CreateStartShortcut=Создать ярлык в меню Пуск
rus.NoKaM=Мастер установки не обнаружил установленной игры Knights and Merchants: The Peasants Rebellion. Оригинальная игра необходима для установки КаМ Ремейк.%n%nУстановка будет отменена.
rus.SteamFirstRun=Оригинальная игра, установленная из Steam должна быть запущена хотя бы 1 раз, чтобы данный установщик КаМ Ремейк смог ее обнаружить и проверить.
rus.CantUpdate=Мастер установки не смог обнаружить версию КаМ Ремейк для обновления. Пожалуйста скачайте и запустите полную версию установщика.%n%nУстановка будет отменена.
rus.OpenAL=Установить OpenAL? (рекоммендуется) Необходимо для работы звука в КаМ Ремейк
rus.ViewReadme=Показать Readme
rus.DeleteSaves=Вы хотите также удалить все сохраненные игры и прогресс всех кампаний?
rus.DeleteMaps=Вы хотите также удалить все карты и кампании?

;Brazilian Portuguese
ptb.CreateStartShortcut=Criar um atalho no menu Iniciar
ptb.NoKaM=O assistente de instalação detectou que você não tem Knights and Merchants: The Peasants Rebellion instalado.%n%nA instalação será abortada.
ptb.CantUpdate=O assistente de instalação foi incapaz de encontrar uma versão existente do KaM Remake para atualizar. Por favor, baixe e instale através do instalador completo.%n%nA instalação será abortada.
ptb.OpenAL=Você deseja que o assistente de instalação instale o OpenAL? (Altamente recomendado) É necessário para o funcionamento dos sons no KaM Remake
ptb.ViewReadme=Ver o Readme

;Italian
ita.CreateStartShortcut=Crea collegamento nel Menu Avvio
ita.NoKaM=La procedura guidata di installazione non ha rilevato alcuna copia di "Knights and Merchants: The Peasants Rebellion". È necessaria l'installazione del gioco originale per poter utilizzare "KaM Remake".%n%nLa procedura di installazione verrà ora annullata.
ita.CantUpdate=La procedura guidata di installazione non ha rilevato alcuna versione di "KaM Remake" da aggiornare. Si prega di scaricare e utilizzare invece il programma di installazione completo.%n%nLa procedura di installazione verrà ora annullata.
ita.OpenAL=Vuoi procedere all'installazione di OpenAL? (Fortemente raccomandata) È necessaria per il corretto funzionamento dell'audio in "KaM Remake"
ita.ViewReadme=Visualizza il file Readme

;Spanish
spa.CreateStartShortcut=Crea un acceso directo en el menú de inicio
spa.NoKaM=El asistente de instalación ha detectado que no tienes Knights and Merchants: The Peasants Rebellion instalado. Usted debe tener instalado el juego original para poder jugar el remake de Kam.%n%nLa instalación se interrumpirá
spa.CantUpdate=El asistente de instalación no ha podido encontrar la versión Kam Remake para poder actualizar. Por favor, descarga y instala la versión completa.%n%nLa instalación se interrumpirá.
spa.OpenAL=¿Quieres que el asistente de instalación instale OpenAL? (Muy recomendable) se requiere para el sonido del juego Kam Remake
spa.ViewReadme=Ver el archivo Readme

;Bulgarian
bul.CreateStartShortcut=Създай пряк път
bul.NoKaM=Инсталацията откри, че нямате инсталирана Knights and Merchants: The Peasants Rebellion. Вие трябва да имате Knights and Merchants: The Peasants Rebellion, за да играете KaM Remake.%n%nИнсталацията се прекратява.
bul.CantUpdate=Инсталацията не успя да намери съществуваща версия на KaM Remake, за да бъде подобрена. Моля изтеглете и инсталирайте пълния инсталатор.%n%nИнсталацията ще се прекрати.
bul.OpenAL=Искате ли инсталацията да инсталира OpenAL? (Силно се препоръчва) Нужно е, за да работи звука в играта.
bul.ViewReadme=Виж "Прочети ме"

;Estonian
est.CreateStartShortcut=Loo start menüü otsetee
est.NoKaM=Paigaldamise programm on avastanud, et Teil ei ole paigaldatud Knights and Merchants: The Peasants Rebellion. Teil peab olema paigaldatud originaal mäng, et mängida mängu KaM Remake.%n%nPaigaldamine katkestakase.
est.CantUpdate=Paigaldamise programm ei leidnud olemas olevat KaM Remake versiooni, mida uuendada. Palun laadige internetist alla täis versioon mängust KaM Remake.%n%nPaigaldamine katkestatakse.
est.OpenAL=Kas te soovite paigaldada programmi OpenAL? (Tungivalt soovitatav) See on vajalik, et helid töötaksid mängus KaM Remake.
est.ViewReadme=Vaadake faili Readme

;Slovak
svk.CreateStartShortcut=Vytvoriť zástupcu v ponuke Štart
svk.NoKaM=Sprievodca inštaláciou zistil, že nemáte nainštalovaný Knight & Merchants: The Peasants Rebellion. Musíte mať nainštalovanú originálnu hru, aby ste mohli hrať KaM Remake.%n%nInštalácia bude prerušená.
svk.CantUpdate=Sprievodca inštaláciou nemohol nájsť existujúcu verziu KaM Remake, je ju potrebné aktualizovať. Prosím, stiahnite a nainštalujte kompletnú inštaláciu.%n%nInštalácia bude prerušená.
svk.OpenAL=Chcete použiť spriveodcu na inštaláciu OpenAL? (Dôrazne odporúčané). Je to potrebné pre zvuky v hre v KAM Remake.
svk.ViewReadme=Pozri súbor Readme

;Romanian
rom.CreateStartShortcut=Creează o scurtătura în meniul de Start
rom.NoKaM=Instalarea a detectat ca nu ai instalat Knights and Merchants: The Peasants Rebellion. Trebuie să ai instalat jocul original pentru a putea juca KaM Remake.%n%nInstalarea se va întrerupe.
rom.CantUpdate=Instalarea nu a putut găsi o versiune care va putea fi updată. Te rog să downloadezi fisierul de instalare complet.%n%nInstalarea se va întrerupe.
rom.OpenAL=Vrei să instalezi OpenAL?(Recomandat) Este necesar pentru sunetele din KaM Remake
rom.ViewReadme=Vizualizeazp fisierul Citeste-ma

;Ukrainian
ukr.CreateStartShortcut=Створити ярлик стартового меню
ukr.NoKaM=Майстер встановлення программи не знайшов оригіналу Knights and Merchants: The Peasants Rebellion на вашому комп`ютері. Ви маєте встановити оригінал для того , щоб грат в KaM Remake.%n%nІнсталяцію скасовано.
ukr.CantUpdate=Майстер встановлення програми не зміг знайти KaM Remake на компютері для того, щоб оновити його. Будь ласка , в першу чергу , завантажте і встановіть повну версію перш ніж встановлювати апдейт.%n%nІнсталяцію скасовано.
ukr.OpenAL=Чи хочете ви щоби майстер встановив OpenAL? (Дуже рекомендується) Він необхідний для роботи звуку у KaM Remake
ukr.ViewReadme=Відкрити Readme

;Norwegian
nor.CreateStartShortcut=Legg til snarvei i Start-menyen
nor.NoKaM=Installasjonsveiviseren oppdaget at du ikke har Knights and Merchants: The Peasants Rebellion installert. Du må ha det originale spillet installert for å spille KaM Remake.%n%nInstallasjonen vil bli avbrutt.
nor.CantUpdate=Installasjonen kunne ikke finne en eksisterende versjon av KaM Remake å oppdatere. Vennligst last ned og installer det fullstendige installasjonsprogrammet i stedet.%n%nInstallasjonen vil bli avbrutt.
nor.OpenAL=Ønsker du at installasjonsveiviseren skal installere OpenAL? (Anbefales sterkt) Det er nødvendig for at lyder skal fungere i KaM Remake
nor.ViewReadme=Vis Readme

;Belarusian
bel.CreateStartShortcut=Стварыць цэтлік ў меню "Пуск"
bel.NoKaM=Майстар ўстаноўкі выявіў што ў вас няма ўсталяванай iгры Knights and Merchants: The Peasants Rebellion. Вы павінны ўсталяваць арыгінальную iгру каб іграць ў KaM Remake.%n%nУстаноўка будзе спынена.
bel.CantUpdate=Майстру ўстаноўкі не ўдаецца знайсці версію KaM Remake для абнаўлення. Калі ласка загрузіце поўны пакет ўстаноўкі.%n%nУстаноўка будзе спынена.
bel.OpenAL=Вы хочаце ўсталяваць OpenAL? (настойліва рэкамендуецца) Гэта неабходна для работы гуку ў KaM Remake
bel.ViewReadme=Адкрыць Readme

;Japanese
jpn.CreateStartShortcut=スタートメニューのショートカットが作成されます。
jpn.NoKaM=インストールウィザードが"Knights and Merchants: The Peasants Rebellion"をインストールしていないの検出されました。KAM リメイクがフレーされるにはオリジナルのゲームはインストールしてはいけません。インストールは中止されました。
jpn.CantUpdate=インストールウィザードは既存のKAMリメイクバージョンが見つかりませんでした。その代わりに全部のインストーラはダウンロートしてインストールしてください。インストールは中止されました。
jpn.OpenAL=インストールウィザードがOpenALをインストールしたいですか「強い推奨」。KAM リメイクの音楽などを聞くと必要です。
jpn.ViewReadme=Readmeが表示されます。

;Turkish
tur.CreateStartShortcut=Başlat menüsü kısayolu oluştur.
tur.NoKaM=Kurulum sihirbazı orijinal Knights and Merchants: The Peasants Rebellion oyununun kurulu olmadığını tespit etti. KaM Remake modunu oynayabilmek için orijinal oyuna sahip olmanız gerekmektedir.%n%nKurulum sihirbazı kapanacaktır.
tur.CantUpdate=Kurulum sihirbazı herhangi bir kurulu KaM Remake versiyonu bulamadı. Lütfen complete installer indirerek kurulum yapınız.%n%nKurulum sihirbazı kapanacaktır.
tur.OpenAL=Kurulum sihirbazının OpenAL kurmasını ister misiniz? (Tavsiye edilir) Seslerin oyun içinde çalışması için gereklidir.
tur.ViewReadme=Beni oku dosyasını aç

;Korean
kor.CreateStartShortcut=시작 메뉴 단축 아이콘 만들기
kor.NoKaM=설치 마법사가 '기사와 상인:농민의 반란'이 설치가 안된것으로 확인되었습니다. '기사와 상인 다시만듬'을 실행하기 위해서는 반드시 원본 게임이 설치되어 있어야 합니다. 설치가 중단 됩니다.
kor.CantUpdate=설치 마법사가 갱신할 '기사와 상인 다시만듬'의 기존 버전을 찾을 수 없습니다. 전체 설치 프로그램 대신에 다운로드하여 설치 해주십시오. 설치가 중단 됩니다.
kor.OpenAL=OpenAL을 설치하기위해 설치 마법사가 필요합니까? (강력하게 추천함) '기사와 상인 다시만듬'에서 소리를 작동하는데 필요합니다.
kor.ViewReadme=읽어보기

;Serbian
srb.CreateStartShortcut=Направите Старт Мену Пречицу
srb.NoKaM=Инсталациони чаробњак је приметио да немате Knights and Merchants: The Peasants Rebellion инсталирано.Морате имати оригиналну игру инсталирану да бисте играли KaM Remake.%n%nИнсталације ће престати са радом.
srb.CantUpdate=Инсталациони чаробњак није могао да нађе постојећу верзију KaM Remake да се усавремени.Молимо вас скините и инсталирајте комплетан инсталер уместо тога.%n%nИнсталација ће престати са радом.
srb.OpenAL=Да ли желите да вам инсталациони чаробњакисталира OpenAL? (Врло препоручљиво) Потребно је да бих ѕвукови радили у KaM Remake.
srb.ViewReadme=Прочитајте Реадме

;Chinese
chn.CreateStartShortcut=创建开始菜单快捷方式
chn.NoKaM=安装向导检测到没有《骑士与商人之农民起义》的安装。为了能玩重制版游戏，必须先安装原版游戏。本安装程序将被终止。
chn.CantUpdate=安装向导无法找到一个存在的重制版能够被升级。请重新下载并安装完整的安装包。本安装程序将被终止。
chn.OpenAL=你想用安装向导来安装OpenAL吗？（强烈推荐）这是音效文件运行的必需程序。
chn.ViewReadme=查看自述文件

;Slovenian
slv.CreateStartShortcut=Ustvari bljižnico na meniju
slv.NoKaM=Čarovnik za namestitev je zaznal da nimate nameščeno igro Knights and Merchants: The Peasants Rebellion. Morate imeti nameščeno originalno igro če želite igrati KaM Remake.%n%nNamestitev bo prekinjena
slv.OpenAL=Ali želite namestiti OpenAL? (Močno priporočeno) potrebno je za elovanje zvokov v igri KaM Remake.
slv.ViewReadme=Poglej si opis


Unpack assessment items in appropriate system-wide location

#define MyAppName "KA Lite"
#define MyAppPublisher "Foundation for Learning Equality"
#define MyAppURL "http://learningequality.org/"
#define MyAppExeName "KA Lite.exe"

#define getKALiteVersion() \
    Local[1] = Exec(SourcePath+"\getversion.bat") == 0 ? StringChange(FileRead(FileOpen(SourcePath+"\version.temp")), " ", "") : "null"

#define TargetVersion = getKALiteVersion();

#expr DeleteFile(SourcePath+"\version.temp")

[Setup]
AppId={#MyAppName}-{#MyAppPublisher}
AppName={#MyAppName}
AppVersion={#TargetVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
LicenseFile=..\ka-lite\LICENSE
OutputDir=..\
OutputBaseFilename=KALiteSetup-{#TargetVersion}
SetupIconFile=logo48.ico
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
UsePreviousAppDir=yes
ChangesEnvironment=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "..\ka-lite\*"; DestDir: "{app}\ka-lite"; Excludes: ".KALITE_SOURCE_DIR,content\assessment,content\assessment\*,content\assessmentitems.sqlite"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\ka-lite\content\*"; DestDir: "{app}\ka-lite\content"; Excludes: "assessment,assessment\*,assessmentitems.sqlite"; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "..\ka-lite\content\assessment\*"; DestDir: "{app}\ka-lite\assessment"; Excludes: "assessmentitems.sqlite"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\ka-lite\content\assessmentitems.sqlite"; DestDir: "{app}\ka-lite\assessment\khan"; Flags: ignoreversion
Source: "..\gui-packed\KA Lite.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\gui-packed\guitools.vbs"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\gui-packed\images\logo48.ico"; DestDir: "{app}\images"; Flags: ignoreversion
Source: "..\python-setup\*"; DestDir: "{app}\python-setup"; Flags: ignoreversion

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "Uninstall KA Lite"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon ; IconFilename: "{app}\images\logo48.ico"

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: shellexec postinstall skipifsilent

[Dirs]
Name: "{app}\"; Permissions: everyone-modify

[InstallDelete]
Type: Files; Name: "{app}\ka-lite\kalite\updates\utils.*"

[UninstallDelete]
Type: filesandordirs; Name: "{app}\ka-lite\python-packages"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\ab_testing"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\basetests"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\caching"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\central"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\coachreports"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\config"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\contact"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\control_panel"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\contentload"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\distributed"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\django_cherrypy_wsgiserver"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\dynamic_assets"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\facility"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\faq"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\foo"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\i18n"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\khanload"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\knowledgemap"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\loadtesting"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\main"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\management"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\playlist"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\registration"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\remoteadmin"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\securesync"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\shared"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\static"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\store"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\student_testing"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\templatetags"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\templates"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\tests"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\testing"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\topic_tools"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\updates"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\utils"
Type: Files; Name: "{app}\ka-lite\kalite\*.pyc"
Type: Files; Name: "{userstartup}\KA Lite.lnk"
Type: Files; Name: "{app}\CONFIG.dat"

[Code]
var
  installFlag : boolean;
  startupFlag : string;
  ServerInformationPage : TInputQueryWizardPage;
  StartupPage : TInputOptionWizardPage;
  isUpgrade : boolean;
  stopServerCode: integer;
  removeOldGuiTool: integer;
  uninstallError: integer;
  saveDatabaseTemp : integer;
  cleanOldKaliteFolder : integer;
  restoreDatabaseTemp : integer;
  forceCancel : boolean;
  prevVerStr : string;
  prevAppBackupDir : string;
  runGitmigrate : boolean;

procedure InitializeWizard;
begin
    isUpgrade := False;
    forceCancel := False;
    runGitmigrate := False;

    if WizardForm.PrevAppDir <> nil then
    begin
        ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C ka-lite\bin\windows\kalite.bat stop', WizardForm.PrevAppDir, SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C del winshortcut.vbs', WizardForm.PrevAppDir, SW_HIDE, ewWaitUntilTerminated, removeOldGuiTool);
    end;

    // Server data
    ServerInformationPage := CreateInputQueryPage(wpSelectDir,
    'Server Information', 'General data',
    'Please specify the server name and a description, then click Next. (you can leave blank both fields if you want to use the default server name or if you do not want to insert a description)');
    ServerInformationPage.Add('Server name:', False);
    ServerInformationPage.Add('Server description:', False);

    // Run at windows startup.
    StartupPage := CreateInputOptionPage(ServerInformationPage.ID,
    'Server Configuration', 'Startup configuration',
    'The server can run automatically. You may choose one of the following options:', True, False);
    StartupPage.Add('Run the server at windows startup');
    StartupPage.Add('Run the server when this user logs in');
    StartupPage.Add('Do not run the server at startup.');
    StartupPage.SelectedValueIndex := 2;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if forceCancel = True then
  begin
    Confirm := False;
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
    result := False;
    if isUpgrade = True then
    begin
        if PageID = ServerInformationPage.ID then
        begin
            result := True;
        end;
        if PageID = wpSelectDir then
        begin
            result := True;
        end;
    end;
end;

procedure RemoveOldInstallation(targetPath : String);
begin
    WizardForm.Hide;
    if Not Exec(ExpandConstant('{cmd}'),'/C ( dir /b "unins***.exe" | findstr /r "unins[0-9][0-9][0-9].exe" ) > tempu & ( for /f "delims=" %A in ( tempu ) do call %A /SILENT /SUPPRESSMSGBOXES ) & del tempu', targetPath, SW_HIDE, ewWaitUntilTerminated, uninstallError) then
    begin
        Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database & xcopy /y /s ka-lite\kalite\database\data.sqlite '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database', targetPath, SW_HIDE, ewWaitUntilTerminated, saveDatabaseTemp);
        Exec(ExpandConstant('{cmd}'),'/C cd .. & del /q "'+targetPath+'\*" & for /d %x in ( "'+targetPath+'\*" ) do @rd /s /q "%x"', targetPath, SW_HIDE, ewWaitUntilTerminated, cleanOldKaliteFolder);
        Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\kalite\database & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database\data.sqlite ka-lite\kalite\database', targetPath, SW_HIDE, ewWaitUntilTerminated, restoreDatabaseTemp);
    end;
    WizardForm.Show;
end;

{ Get the previous version number by checking the uninstall key registry values. }
{ IS writes quite a bit of information to the registry by default: https://github.com/jrsoftware/issrc/blob/5203240a7de9b83c5432bee0b5b09d467869a02b/Projects/Install.pas#L434 }
procedure GetPreviousVersion;
var
    subkey : String;
begin
    subkey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\KA Lite-Foundation for Learning Equality_is1';
    prevVerStr := ''
    { 32-bit programs have a virtualized registry on 64-bit windows. So check all possible root keys. }
    if Not RegQueryStringValue(HKLM, subkey, 'DisplayVersion', prevVerStr) then
    begin
        if Not RegQueryStringValue(HKCU, subkey, 'DisplayVersion', prevVerStr) then
        begin
            if IsWin64 then
            begin
                if Not RegQueryStringValue(HKLM64, subkey, 'DisplayVersion', prevVerStr) then
                begin
                    if Not RegQueryStringValue(HKCU64, subkey, 'DisplayVersion', prevVerStr) then
                    begin
                        { Couldn't determine the previous version, so prevVerStr is '' }
                    end;
                end;
            end;
        end;
    end;
end;

procedure ConfirmUpgradeDialog;
begin
    if MsgBox('We have detected an existing KA Lite installation; would you like to upgrade?', mbInformation,  MB_YESNO or MB_DEFBUTTON1) = IDYES then
    begin
        isUpgrade := True;
    end
    else if MsgBox('Installing fresh will delete all of your existing data; is this what you really want to do?', mbInformation,  MB_YESNO or MB_DEFBUTTON2) = IDYES then
    begin
        isUpgrade := False;
    end
    else
    begin
        isUpgrade := True;
    end;
end;

procedure Backup013Files;
var
    prevDBDir, prevContentDir: String;
    resCode: integer;
begin
    { Copy the old database and content folders, preserving the dir structure, then after installing then new files... }
    { ...run gitmigrate management command and delete the old stuff. }
    prevAppBackupDir := ExpandConstant('{tmp}') + '\prev-ka-lite';  // Expand this when we use it, instead of earlier.
    prevDBDir := WizardForm.PrevAppDir + '\ka-lite\kalite\database';
    prevContentDir := WizardForm.PrevAppDir + '\ka-lite\content';

    if Not ForceDirectories(prevAppBackupDir + '\kalite\') then
    begin
        MsgBox('Fatal error' #13#13 'Failed to create backup directories at: ' + prevAppBackupDir, mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;

    MsgBox('Setup will now copy your prior user data for migration. If you have a lot of data, this may take some time!', mbInformation, MB_OK);

    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevDBDir + '" "' + prevAppBackupDir + '\kalite\database\" /E "', '', SW_HIDE, ewWaitUntilTerminated, resCode);
    if resCode <> 0 then
    begin
        MsgBox('Fatal error' #13#13 'Failed to backup database directory.', mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevContentDir + '" "' + prevAppBackupDir + '\content\" /E"', '', SW_HIDE, ewWaitUntilTerminated, resCode);
    if resCode <> 0 then
    begin
        MsgBox('Fatal error' #13#13 'Failed to backup content directory.', mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;

    runGitmigrate := True;
end;

procedure HandleUpgrade(targetPath : String);
begin
    GetPreviousVersion;
    if FileExists(targetPath + '\ka-lite\kalite\database\data.sqlite') then
    begin
        ConfirmUpgradeDialog;
        if Not isUpgrade then
        begin
            if Not DeleteFile(targetPath + '\ka-lite\kalite\database\data.sqlite') then
            begin
                MsgBox('Error' #13#13 'Failed to delete the old database as requested; aborting the install.', mbError, MB_OK);
                forceCancel := True;
                WizardForm.Close;
            end;
        end
        else
        begin
            { This is where version-specific migration stuff should happen. }
            if CompareStr(prevVerStr, '0.13.99') < 0 then
            begin
                if CompareStr('{#TargetVersion}', '0.14.0') >= 0 then
                begin
                    Backup013Files;
                end;
            end;
        end;
    { forceCancel will be true if something went awry in Backup013Files... abort instead of trampling the user's data. }
    if Not forceCancel then
        RemoveOldInstallation(targetPath);
    end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
    result := True;

    if CurPageID = wpLicense then
    begin
        if WizardForm.PrevAppDir <> nil then
            HandleUpgrade(WizardForm.PrevAppDir);
    end;

    if CurPageID = wpSelectDir then
    begin
        { Unclear what the logic here is. This is only executed if HandleUpgrade was not previously run. }
        if Not isUpgrade then
            HandleUpgrade(ExpandConstant('{app}'));
    end;
end;

procedure HandlePythonSetup;
var
    installPythonErrorCode : Integer;
begin
    if(MsgBox('Python error' #13#13 'Python 2.7.9+ is required to install KA Lite on Windows; do you wish to first install Python 2.7.10, before continuing with the installation of KA Lite?', mbConfirmation, MB_YESNO) = idYes) then
    begin
        ExtractTemporaryFile('python-2.7.10.msi');
        ShellExec('open', ExpandConstant('{tmp}')+'\python-2.7.10.msi', '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, installPythonErrorCode);
    end
    else begin
        MsgBox('Error' #13#13 'You must have Python 2.7.9+ installed to proceed! Installation will now exit.', mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;
end;

{ Used in GetPipPath below }
const
    DEFAULT_PATH = '\Python27\Scripts\pip.exe';

{ Returns the path of pip.exe on the system. }
{ Tries several different locations before prompting user. }
function GetPipPath: string;
var
    path : string;
    i : integer;
begin
    for i := Ord('C') to Ord('H') do
    begin
        path := Chr(i) + ':' + DEFAULT_PATH;
        if FileExists(path) then
        begin
            Result := path;
            exit;
        end;
    end;
    MsgBox('Could not find pip.exe. Please select the location of pip.exe to continue installation.', mbInformation, MB_OK);
    if GetOpenFileName('Please select pip.exe', path, '', 'All files (*.*)|*.*', 'exe') then
    begin
        Result := path;
    end
    else begin
        MsgBox('Fatal error'#13#13'Please install pip and try again.', mbError, MB_OK);
        forceCancel := True;
        Result := '';
    end;
end;

procedure HandlePipSetup;
var
    PipCommand: string;
    PipPath: string;
    ErrorCode: integer;

begin
    PipPath := GetPipPath;
    if PipPath = '' then
        exit;
    PipCommand := 'install "' + ExpandConstant('{app}\ka-lite\dist\ka-lite-static-')  + '{#TargetVersion}' + '.zip"';

    MsgBox('Setup will now unpack dependencies for your installation.', mbInformation, MB_OK);
    if not ShellExec('open', PipPath, PipCommand, '', SW_HIDE, ewWaitUntilTerminated, ErrorCode) then
    begin
      MsgBox('Critical error.' #13#13 'Dependencies have failed to install. Error Number: ' + IntToStr(ErrorCode), mbInformation, MB_OK);
      forceCancel := True;
      WizardForm.Close;
    end;
end;

function InitializeSetup(): Boolean;
var
  PythonVersionCodeCheck: integer;
  killErrorCode: integer;
begin
    installFlag:=true;
    Result := true;
    startupFlag:='';

    ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, killErrorCode)
    ShellExec('open', 'tskill.exe', ' "KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, killErrorCode);

    RegDeleteValue(HKCU, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', ExpandConstant('{#MyAppName}'));

    if ShellExec('open', 'python.exe','-c "import sys; (sys.version_info >= (2, 7, 9,) and sys.version_info < (3,) and sys.exit(0)) or sys.exit(1)"', '', SW_HIDE, ewWaitUntilTerminated, PythonVersionCodeCheck) then
    begin
        if PythonVersionCodeCheck = 1 then
        begin
            HandlePythonSetup();
        end;
    end
    else
    begin
        HandlePythonSetup();
    end;
end;

function InitializeUninstall(): Boolean;
var
ErrorCode: Integer;
begin
  ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  ShellExec('open', ExpandConstant('{app}') + '\ka-lite\bin\windows\kalite.bat stop', '', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  result := True;
end;

{ Runs the gitmigrate management command introduced in 0.14 on the backup of a 0.13 installation }
procedure DoGitMigrate;
var
    retCodeContent, retCodeDB, retCode : integer;
begin
    MsgBox('Migrating old data to current user''s %USERPROFILE%\.kalite\ directory.', mbInformation, MB_OK);
    Exec(ExpandConstant('{cmd}'), '/S /C "mkdir "%USERPROFILE%\.kalite""', '', SW_SHOW, ewWaitUntilTerminated, retCode);
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevAppBackupDir + '\content" "%USERPROFILE%\.kalite\content\" /E /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCodeContent);
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevAppBackupDir + '\kalite\database" "%USERPROFILE%\.kalite\database\" /E /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCodeDB);
    if (retCodeContent <> 0) or (retCodeDB <> 0) then
    begin
        Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevAppBackupDir + '" "' + ExpandConstant('{app}') + '\kalite-backup\" /E /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCode);
        MsgBox('Unable to migrate your data. Your data is still backed up at the directory: ' + ExpandConstant('{app}') + '\kalite-backup', mbError, MB_OK);
    end;
end;

{ Completes the setup with bundled empty database file. }
procedure DoSetup;
var
    setupCommand: string;
    retCode: integer;
begin
    { Copy the bundled empty db to the proper location. }
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + ExpandConstant('{app}') + '\ka-lite\kalite\database" "%USERPROFILE%\.kalite\database\" /E /Y"', '', SW_HIDE, ewWaitUntilTerminated, retCode);
    MsgBox('Setup will now configure the database. This operation may take a few minutes. Please be patient.', mbInformation, MB_OK);
    setupCommand := 'kalite manage setup --noinput --hostname="'+ServerInformationPage.Values[0]+'" --description="'+ServerInformationPage.Values[1]+'"';
    if Not ShellExec('open', 'python.exe', setupCommand, ExpandConstant('{app}')+'\ka-lite\bin', SW_HIDE, ewWaitUntilTerminated, retCode) then
    begin
        MsgBox('Critical error.' #13#13 'Setup has failed to initialize the database; aborting the install.', mbInformation, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  StartupCode: integer;
  moveKaliteFolderTemp: integer;
  moveContentFolderTemp: integer;
  cleanKaliteFolder: integer;
  restoreKaliteFolder: integer;
  restoreContentFolder: integer;
  informationBoxFlagged: boolean;

begin
    if CurStep = ssInstall then
    begin
        informationBoxFlagged :=False;

        ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C ka-lite\bin\windows\kalite.bat stop', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C del winshortcut.vbs', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, removeOldGuiTool);

        if DirExists(ExpandConstant('{app}') + '\kalite') then
        begin
            MsgBox('KA Lite old data structure' #13#13 'Setup detected that you have the old file structure. Setup will now move data to update the structure. Please be patient; this may take some time.', mbInformation, MB_OK);
            informationBoxFlagged :=True;
            Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\kalite & xcopy /y /s kalite\* '+ExpandConstant('{tmp}')+'\ka-lite\kalite', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, moveKaliteFolderTemp);
        end;

        if DirExists(ExpandConstant('{app}') + '\content') then
        begin
            if Not informationBoxFlagged then
            begin
                MsgBox('KA Lite old data structure' #13#13 'Setup detected that you have the old file structure. Setup will now move data to update the structure. Please be patient; this may take some time.', mbInformation, MB_OK);
                informationBoxFlagged :=True;
            end;
            Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\content & xcopy /y /s content\* '+ExpandConstant('{tmp}')+'\ka-lite\content', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, moveContentFolderTemp);
        end;

        if informationBoxFlagged then
        begin
            Exec(ExpandConstant('{cmd}'),'/C cd .. & del /q "'+ExpandConstant('{app}')+'\*" & for /d %x in ( "'+ExpandConstant('{app}')+'\*" ) do @rd /s /q "%x"', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, cleanKaliteFolder);

            if DirExists(ExpandConstant('{tmp}')+'\ka-lite\kalite') then
            begin
                Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\kalite & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\kalite\* ka-lite\kalite', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, restoreKaliteFolder);
            end;

            if DirExists(ExpandConstant('{tmp}')+'\ka-lite\content') then
            begin
                Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\content & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\content\* ka-lite\content', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, restoreContentFolder);
            end;
        end;

    end;

    if CurStep = ssPostInstall then
    begin
        if installFlag then
        begin
            HandlePipSetup();

            { Add KALITE_ROOT_DATA_PATH to environment variables. A workaround for setting kalite.ROOT_DATA_PATH }
            { In the future, the windows installer should use setuptools to avoid OS-dependent workarounds like this. }
            RegWriteStringValue(
                HKLM,
                'System\CurrentControlSet\Control\Session Manager\Environment',
                'KALITE_ROOT_DATA_PATH',
                ExpandConstant('{app}\ka-lite\')
            );

            { Migrate old database if applicable, otherwise create a new one }
            if runGitmigrate and Not forceCancel then
            begin
                DoGitMigrate;
            end
            else if Not forceCancel then
            begin
                DoSetup;
            end;

            if StartupPage.SelectedValueIndex = 0 then
            begin
                if ShellExec('open','guitools.vbs','4', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, StartupCode) then
                begin
                    if Not SaveStringToFile(ExpandConstant('{app}')+'\CONFIG.dat', 'RUN_AT_STARTUP:TRUE;' + #13#10, False) then
                    begin
                        MsgBox('Configuration file error.' #13#13 'Setup has failed to add the entry in the configuration file to run KA Lite at Windows startup. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                    end;
                end
                else begin
                    MsgBox('GUI tools error.' #13#13 'Setup has failed to register a task to run KA Lite at Windows startup. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                end;
            end
            else if StartupPage.SelectedValueIndex = 1 then
            begin
                if ShellExec('open', 'guitools.vbs', '0', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, StartupCode) then
                begin
                    if Not SaveStringToFile(ExpandConstant('{app}')+'\CONFIG.dat', 'RUN_AT_USER_LOGIN:TRUE;' + #13#10, False) then
                    begin
                        MsgBox('Configuration file error.' #13#13 'Setup has failed to add the entry in the configuration file to run KA Lite on user login. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                    end;
                end
                else begin
                    MsgBox('GUI tools error.' #13#13 'Setup has failed to add the shortcut at the startup folder to run KA Lite on user login. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                end;
            end;
        end;
    end;

end;

#define MyAppName "KA Lite"
#define MyAppPublisher "Foundation for Learning Equality"
#define MyAppURL "http://learningequality.org/"
#define MyAppExeName "KA Lite.exe"

#define getKALiteVersion() \
    Local[1] = Exec(SourcePath+"\getversion.bat") == 0 ? StringChange(FileRead(FileOpen(SourcePath+"\version.temp")), " ", "") : "null"

#define TargetVersion = getKALiteVersion();

#expr DeleteFile(SourcePath+"\version.temp")

[Setup]
AppId={#MyAppName}-{#MyAppPublisher}
AppName={#MyAppName}
AppVersion={#TargetVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
LicenseFile=..\ka-lite\LICENSE
OutputDir=..\
OutputBaseFilename=KALiteSetup-{#TargetVersion}
SetupIconFile=logo48.ico
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
UsePreviousAppDir=yes
ChangesEnvironment=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "..\ka-lite\*"; DestDir: "{app}\ka-lite"; Excludes: ".KALITE_SOURCE_DIR"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\ka-lite\content\*"; DestDir: "{app}\ka-lite\content"; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "..\gui-packed\KA Lite.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\gui-packed\guitools.vbs"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\gui-packed\images\logo48.ico"; DestDir: "{app}\images"; Flags: ignoreversion
Source: "..\python-setup\*"; DestDir: "{app}\python-setup"; Flags: ignoreversion

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "Uninstall KA Lite"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon ; IconFilename: "{app}\images\logo48.ico"

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: shellexec postinstall skipifsilent

[Dirs]
Name: "{app}\"; Permissions: everyone-modify

[InstallDelete]
Type: Files; Name: "{app}\ka-lite\kalite\updates\utils.*"

[UninstallDelete]
Type: filesandordirs; Name: "{app}\ka-lite\python-packages"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\ab_testing"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\basetests"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\caching"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\central"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\coachreports"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\config"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\contact"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\control_panel"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\contentload"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\distributed"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\django_cherrypy_wsgiserver"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\dynamic_assets"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\facility"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\faq"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\foo"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\i18n"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\khanload"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\knowledgemap"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\loadtesting"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\main"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\management"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\playlist"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\registration"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\remoteadmin"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\securesync"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\shared"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\static"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\store"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\student_testing"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\templatetags"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\templates"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\tests"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\testing"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\topic_tools"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\updates"
Type: filesandordirs; Name: "{app}\ka-lite\kalite\utils"
Type: Files; Name: "{app}\ka-lite\kalite\*.pyc"
Type: Files; Name: "{userstartup}\KA Lite.lnk"
Type: Files; Name: "{app}\CONFIG.dat"

[Code]
var
  installFlag : boolean;
  startupFlag : string;
  ServerInformationPage : TInputQueryWizardPage;
  StartupPage : TInputOptionWizardPage;
  isUpgrade : boolean;
  stopServerCode: integer;
  removeOldGuiTool: integer;
  uninstallError: integer;
  saveDatabaseTemp : integer;
  cleanOldKaliteFolder : integer;
  restoreDatabaseTemp : integer;
  forceCancel : boolean;
  prevVerStr : string;
  prevAppBackupDir : string;
  runGitmigrate : boolean;

procedure InitializeWizard;
begin
    isUpgrade := False;
    forceCancel := False;
    runGitmigrate := False;

    if WizardForm.PrevAppDir <> nil then
    begin
        ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C ka-lite\bin\windows\kalite.bat stop', WizardForm.PrevAppDir, SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C del winshortcut.vbs', WizardForm.PrevAppDir, SW_HIDE, ewWaitUntilTerminated, removeOldGuiTool);
    end;

    // Server data
    ServerInformationPage := CreateInputQueryPage(wpSelectDir,
    'Server Information', 'General data',
    'Please specify the server name and a description, then click Next. (you can leave blank both fields if you want to use the default server name or if you do not want to insert a description)');
    ServerInformationPage.Add('Server name:', False);
    ServerInformationPage.Add('Server description:', False);

    // Run at windows startup.
    StartupPage := CreateInputOptionPage(ServerInformationPage.ID,
    'Server Configuration', 'Startup configuration',
    'The server can run automatically. You may choose one of the following options:', True, False);
    StartupPage.Add('Run the server at windows startup');
    StartupPage.Add('Run the server when this user logs in');
    StartupPage.Add('Do not run the server at startup.');
    StartupPage.SelectedValueIndex := 2;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if forceCancel = True then
  begin
    Confirm := False;
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
    result := False;
    if isUpgrade = True then
    begin
        if PageID = ServerInformationPage.ID then
        begin
            result := True;
        end;
        if PageID = wpSelectDir then
        begin
            result := True;
        end;
    end;
end;

procedure RemoveOldInstallation(targetPath : String);
begin
    WizardForm.Hide;
    if Not Exec(ExpandConstant('{cmd}'),'/C ( dir /b "unins***.exe" | findstr /r "unins[0-9][0-9][0-9].exe" ) > tempu & ( for /f "delims=" %A in ( tempu ) do call %A /SILENT /SUPPRESSMSGBOXES ) & del tempu', targetPath, SW_HIDE, ewWaitUntilTerminated, uninstallError) then
    begin
        Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database & xcopy /y /s ka-lite\kalite\database\data.sqlite '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database', targetPath, SW_HIDE, ewWaitUntilTerminated, saveDatabaseTemp);
        Exec(ExpandConstant('{cmd}'),'/C cd .. & del /q "'+targetPath+'\*" & for /d %x in ( "'+targetPath+'\*" ) do @rd /s /q "%x"', targetPath, SW_HIDE, ewWaitUntilTerminated, cleanOldKaliteFolder);
        Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\kalite\database & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database\data.sqlite ka-lite\kalite\database', targetPath, SW_HIDE, ewWaitUntilTerminated, restoreDatabaseTemp);
    end;
    WizardForm.Show;
end;

{ Get the previous version number by checking the uninstall key registry values. }
{ IS writes quite a bit of information to the registry by default: https://github.com/jrsoftware/issrc/blob/5203240a7de9b83c5432bee0b5b09d467869a02b/Projects/Install.pas#L434 }
procedure GetPreviousVersion;
var
    subkey : String;
begin
    subkey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\KA Lite-Foundation for Learning Equality_is1';
    prevVerStr := ''
    { 32-bit programs have a virtualized registry on 64-bit windows. So check all possible root keys. }
    if Not RegQueryStringValue(HKLM, subkey, 'DisplayVersion', prevVerStr) then
    begin
        if Not RegQueryStringValue(HKCU, subkey, 'DisplayVersion', prevVerStr) then
        begin
            if IsWin64 then
            begin
                if Not RegQueryStringValue(HKLM64, subkey, 'DisplayVersion', prevVerStr) then
                begin
                    if Not RegQueryStringValue(HKCU64, subkey, 'DisplayVersion', prevVerStr) then
                    begin
                        { Couldn't determine the previous version, so prevVerStr is '' }
                    end;
                end;
            end;
        end;
    end;
end;

procedure ConfirmUpgradeDialog;
begin
    if MsgBox('We have detected an existing KA Lite installation; would you like to upgrade?', mbInformation,  MB_YESNO or MB_DEFBUTTON1) = IDYES then
    begin
        isUpgrade := True;
    end
    else if MsgBox('Installing fresh will delete all of your existing data; is this what you really want to do?', mbInformation,  MB_YESNO or MB_DEFBUTTON2) = IDYES then
    begin
        isUpgrade := False;
    end
    else
    begin
        isUpgrade := True;
    end;
end;

procedure Backup013Files;
var
    prevDBDir, prevContentDir: String;
    resCode: integer;
begin
    { Copy the old database and content folders, preserving the dir structure, then after installing then new files... }
    { ...run gitmigrate management command and delete the old stuff. }
    prevAppBackupDir := ExpandConstant('{tmp}') + '\prev-ka-lite';  // Expand this when we use it, instead of earlier.
    prevDBDir := WizardForm.PrevAppDir + '\ka-lite\kalite\database';
    prevContentDir := WizardForm.PrevAppDir + '\ka-lite\content';

    if Not ForceDirectories(prevAppBackupDir + '\kalite\') then
    begin
        MsgBox('Fatal error' #13#13 'Failed to create backup directories at: ' + prevAppBackupDir, mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;

    MsgBox('Setup will now copy your prior user data for migration. If you have a lot of data, this may take some time!', mbInformation, MB_OK);

    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevDBDir + '" "' + prevAppBackupDir + '\kalite\database\" /E "', '', SW_HIDE, ewWaitUntilTerminated, resCode);
    if resCode <> 0 then
    begin
        MsgBox('Fatal error' #13#13 'Failed to backup database directory.', mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevContentDir + '" "' + prevAppBackupDir + '\content\" /E"', '', SW_HIDE, ewWaitUntilTerminated, resCode);
    if resCode <> 0 then
    begin
        MsgBox('Fatal error' #13#13 'Failed to backup content directory.', mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;

    runGitmigrate := True;
end;

procedure HandleUpgrade(targetPath : String);
begin
    GetPreviousVersion;
    if FileExists(targetPath + '\ka-lite\kalite\database\data.sqlite') then
    begin
        ConfirmUpgradeDialog;
        if Not isUpgrade then
        begin
            if Not DeleteFile(targetPath + '\ka-lite\kalite\database\data.sqlite') then
            begin
                MsgBox('Error' #13#13 'Failed to delete the old database as requested; aborting the install.', mbError, MB_OK);
                forceCancel := True;
                WizardForm.Close;
            end;
        end
        else
        begin
            { This is where version-specific migration stuff should happen. }
            if CompareStr(prevVerStr, '0.13.99') < 0 then
            begin
                if CompareStr('{#TargetVersion}', '0.14.0') >= 0 then
                begin
                    Backup013Files;
                end;
            end;
        end;
    { forceCancel will be true if something went awry in Backup013Files... abort instead of trampling the user's data. }
    if Not forceCancel then
        RemoveOldInstallation(targetPath);
    end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
    result := True;

    if CurPageID = wpLicense then
    begin
        if WizardForm.PrevAppDir <> nil then
            HandleUpgrade(WizardForm.PrevAppDir);
    end;

    if CurPageID = wpSelectDir then
    begin
        { Unclear what the logic here is. This is only executed if HandleUpgrade was not previously run. }
        if Not isUpgrade then
            HandleUpgrade(ExpandConstant('{app}'));
    end;
end;

procedure HandlePythonSetup;
var
    installPythonErrorCode : Integer;
begin
    if(MsgBox('Python error' #13#13 'Python 2.7.9+ is required to install KA Lite on Windows; do you wish to first install Python 2.7.10, before continuing with the installation of KA Lite?', mbConfirmation, MB_YESNO) = idYes) then
    begin
        ExtractTemporaryFile('python-2.7.10.msi');
        ShellExec('open', ExpandConstant('{tmp}')+'\python-2.7.10.msi', '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, installPythonErrorCode);
    end
    else begin
        MsgBox('Error' #13#13 'You must have Python 2.7.9+ installed to proceed! Installation will now exit.', mbError, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;
end;

{ Used in GetPipPath below }
const
    DEFAULT_PATH = '\Python27\Scripts\pip.exe';

{ Returns the path of pip.exe on the system. }
{ Tries several different locations before prompting user. }
function GetPipPath: string;
var
    path : string;
    i : integer;
begin
    for i := Ord('C') to Ord('H') do
    begin
        path := Chr(i) + ':' + DEFAULT_PATH;
        if FileExists(path) then
        begin
            Result := path;
            exit;
        end;
    end;
    MsgBox('Could not find pip.exe. Please select the location of pip.exe to continue installation.', mbInformation, MB_OK);
    if GetOpenFileName('Please select pip.exe', path, '', 'All files (*.*)|*.*', 'exe') then
    begin
        Result := path;
    end
    else begin
        MsgBox('Fatal error'#13#13'Please install pip and try again.', mbError, MB_OK);
        forceCancel := True;
        Result := '';
    end;
end;

procedure HandlePipSetup;
var
    PipCommand: string;
    PipPath: string;
    ErrorCode: integer;

begin
    PipPath := GetPipPath;
    if PipPath = '' then
        exit;
    PipCommand := 'install "' + ExpandConstant('{app}\ka-lite\dist\ka-lite-static-')  + '{#TargetVersion}' + '.zip"';

    MsgBox('Setup will now unpack dependencies for your installation.', mbInformation, MB_OK);
    if not ShellExec('open', PipPath, PipCommand, '', SW_HIDE, ewWaitUntilTerminated, ErrorCode) then
    begin
      MsgBox('Critical error.' #13#13 'Dependencies have failed to install. Error Number: ' + IntToStr(ErrorCode), mbInformation, MB_OK);
      forceCancel := True;
      WizardForm.Close;
    end;
end;

function InitializeSetup(): Boolean;
var
  PythonVersionCodeCheck: integer;
  killErrorCode: integer;
begin
    installFlag:=true;
    Result := true;
    startupFlag:='';

    ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, killErrorCode)
    ShellExec('open', 'tskill.exe', ' "KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, killErrorCode);

    RegDeleteValue(HKCU, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', ExpandConstant('{#MyAppName}'));

    if ShellExec('open', 'python.exe','-c "import sys; (sys.version_info >= (2, 7, 9,) and sys.version_info < (3,) and sys.exit(0)) or sys.exit(1)"', '', SW_HIDE, ewWaitUntilTerminated, PythonVersionCodeCheck) then
    begin
        if PythonVersionCodeCheck = 1 then
        begin
            HandlePythonSetup();
        end;
    end
    else
    begin
        HandlePythonSetup();
    end;
end;

function InitializeUninstall(): Boolean;
var
ErrorCode: Integer;
begin
  ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  ShellExec('open', ExpandConstant('{app}') + '\ka-lite\bin\windows\kalite.bat stop', '', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  result := True;
end;

{ Runs the gitmigrate management command introduced in 0.14 on the backup of a 0.13 installation }
procedure DoGitMigrate;
var
    retCodeContent, retCodeDB, retCode : integer;
begin
    MsgBox('Migrating old data to current user''s %USERPROFILE%\.kalite\ directory.', mbInformation, MB_OK);
    Exec(ExpandConstant('{cmd}'), '/S /C "mkdir "%USERPROFILE%\.kalite""', '', SW_SHOW, ewWaitUntilTerminated, retCode);
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevAppBackupDir + '\content" "%USERPROFILE%\.kalite\content\" /E /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCodeContent);
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevAppBackupDir + '\kalite\database" "%USERPROFILE%\.kalite\database\" /E /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCodeDB);
    if (retCodeContent <> 0) or (retCodeDB <> 0) then
    begin
        Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + prevAppBackupDir + '" "' + ExpandConstant('{app}') + '\kalite-backup\" /E /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCode);
        MsgBox('Unable to migrate your data. Your data is still backed up at the directory: ' + ExpandConstant('{app}') + '\kalite-backup', mbError, MB_OK);
    end;
end;

{ Completes the setup with bundled empty database file. }
procedure DoSetup;
var
    setupCommand: string;
    retCode: integer;
begin
    { Copy the bundled empty db to the proper location. }
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + ExpandConstant('{app}') + '\ka-lite\kalite\database" "%USERPROFILE%\.kalite\database\" /E /Y"', '', SW_HIDE, ewWaitUntilTerminated, retCode);
    MsgBox('Setup will now configure the database. This operation may take a few minutes. Please be patient.', mbInformation, MB_OK);
    setupCommand := 'kalite manage setup --noinput --hostname="'+ServerInformationPage.Values[0]+'" --description="'+ServerInformationPage.Values[1]+'"';
    if Not ShellExec('open', 'python.exe', setupCommand, ExpandConstant('{app}')+'\ka-lite\bin', SW_HIDE, ewWaitUntilTerminated, retCode) then
    begin
        MsgBox('Critical error.' #13#13 'Setup has failed to initialize the database; aborting the install.', mbInformation, MB_OK);
        forceCancel := True;
        WizardForm.Close;
    end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  StartupCode: integer;
  moveKaliteFolderTemp: integer;
  moveContentFolderTemp: integer;
  cleanKaliteFolder: integer;
  restoreKaliteFolder: integer;
  restoreContentFolder: integer;
  informationBoxFlagged: boolean;

begin
    if CurStep = ssInstall then
    begin
        informationBoxFlagged :=False;

        ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C ka-lite\bin\windows\kalite.bat stop', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C del winshortcut.vbs', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, removeOldGuiTool);

        if DirExists(ExpandConstant('{app}') + '\kalite') then
        begin
            MsgBox('KA Lite old data structure' #13#13 'Setup detected that you have the old file structure. Setup will now move data to update the structure. Please be patient; this may take some time.', mbInformation, MB_OK);
            informationBoxFlagged :=True;
            Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\kalite & xcopy /y /s kalite\* '+ExpandConstant('{tmp}')+'\ka-lite\kalite', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, moveKaliteFolderTemp);
        end;

        if DirExists(ExpandConstant('{app}') + '\content') then
        begin
            if Not informationBoxFlagged then
            begin
                MsgBox('KA Lite old data structure' #13#13 'Setup detected that you have the old file structure. Setup will now move data to update the structure. Please be patient; this may take some time.', mbInformation, MB_OK);
                informationBoxFlagged :=True;
            end;
            Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\content & xcopy /y /s content\* '+ExpandConstant('{tmp}')+'\ka-lite\content', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, moveContentFolderTemp);
        end;

        if informationBoxFlagged then
        begin
            Exec(ExpandConstant('{cmd}'),'/C cd .. & del /q "'+ExpandConstant('{app}')+'\*" & for /d %x in ( "'+ExpandConstant('{app}')+'\*" ) do @rd /s /q "%x"', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, cleanKaliteFolder);

            if DirExists(ExpandConstant('{tmp}')+'\ka-lite\kalite') then
            begin
                Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\kalite & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\kalite\* ka-lite\kalite', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, restoreKaliteFolder);
            end;

            if DirExists(ExpandConstant('{tmp}')+'\ka-lite\content') then
            begin
                Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\content & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\content\* ka-lite\content', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, restoreContentFolder);
            end;
        end;

    end;

    if CurStep = ssPostInstall then
    begin
        if installFlag then
        begin
            HandlePipSetup();

            { Add KALITE_ROOT_DATA_PATH to environment variables. A workaround for setting kalite.ROOT_DATA_PATH }
            { In the future, the windows installer should use setuptools to avoid OS-dependent workarounds like this. }
            RegWriteStringValue(
                HKLM,
                'System\CurrentControlSet\Control\Session Manager\Environment',
                'KALITE_ROOT_DATA_PATH',
                ExpandConstant('{app}\ka-lite\')
            );

            { Migrate old database if applicable, otherwise create a new one }
            if runGitmigrate and Not forceCancel then
            begin
                DoGitMigrate;
            end
            else if Not forceCancel then
            begin
                DoSetup;
            end;

            if StartupPage.SelectedValueIndex = 0 then
            begin
                if ShellExec('open','guitools.vbs','4', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, StartupCode) then
                begin
                    if Not SaveStringToFile(ExpandConstant('{app}')+'\CONFIG.dat', 'RUN_AT_STARTUP:TRUE;' + #13#10, False) then
                    begin
                        MsgBox('Configuration file error.' #13#13 'Setup has failed to add the entry in the configuration file to run KA Lite at Windows startup. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                    end;
                end
                else begin
                    MsgBox('GUI tools error.' #13#13 'Setup has failed to register a task to run KA Lite at Windows startup. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                end;
            end
            else if StartupPage.SelectedValueIndex = 1 then
            begin
                if ShellExec('open', 'guitools.vbs', '0', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, StartupCode) then
                begin
                    if Not SaveStringToFile(ExpandConstant('{app}')+'\CONFIG.dat', 'RUN_AT_USER_LOGIN:TRUE;' + #13#10, False) then
                    begin
                        MsgBox('Configuration file error.' #13#13 'Setup has failed to add the entry in the configuration file to run KA Lite on user login. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                    end;
                end
                else begin
                    MsgBox('GUI tools error.' #13#13 'Setup has failed to add the shortcut at the startup folder to run KA Lite on user login. The installation may proceed and you can set this option later while using KA Lite.', mbError, MB_OK);
                end;
            end;
        end;
    end;

end;


Update dotnetfx20sp2lp.iss

Update dotnetfx20sp2lp.iss

//http://www.microsoft.com/downloads/details.aspx?FamilyID=c69789e0-a4fa-4b2e-a6b5-3b3695825992

[CustomMessages]
de.dotnetfx20sp2lp_title=.NET Framework 2.0 SP2 Sprachpaket: Deutsch
es.dotnetfx20sp2lp_title=.NET Framework 2.0 SP2 paquete de idioma: Español

de.dotnetfx20sp2lp_size=3,4 MB
es.dotnetfx20sp2lp_size=3,4 MB

de.dotnetfx20sp2lp_size_x64=5 MB
es.dotnetfx20sp2lp_size_x64=4,9 MB

;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
de.dotnetfx20sp2lp_lcid=1031
es.dotnetfx20sp2lp_lcid=3082

de.dotnetfx20sp2lp_url=http://download.microsoft.com/download/0/b/1/0b175c8e-34bd-46c0-bfcd-af8d33770c58/netfx20sp2_x86de.exe
de.dotnetfx20sp2lp_url_x64=http://download.microsoft.com/download/4/e/c/4ec67a11-879d-4550-9c25-fd9ab4261b46/netfx20sp2_x64de.exe
es.dotnetfx20sp2lp_url=http://download.microsoft.com/download/2/5/f/25f168c7-ab97-4f04-8185-db316f85b714/netfx20sp2_x86es.exe
es.dotnetfx20sp2lp_url_x64=http://download.microsoft.com/download/0/7/a/07a33922-e5e4-444d-a67d-12726e1fbb90/netfx20sp2_x64es.exe

[Code]
procedure dotnetfx20sp2lp();
begin
	if (ActiveLanguage() <> 'en') then begin
		if (netfxspversion(NetFx20, CustomMessage('dotnetfx20sp2lp_lcid')) < 2) then
			AddProduct('dotnetfx20sp2' + GetArchitectureString() + '_' + ActiveLanguage() + '.exe',
				'/lang:enu /passive /norestart"',
				CustomMessage('dotnetfx20sp2lp_title'),
				CustomMessage('dotnetfx20sp2lp_size' + GetArchitectureString()),
				CustomMessage('dotnetfx20sp2lp_url' + GetArchitectureString()),
				false, false);
	end;
end;

//http://www.microsoft.com/downloads/details.aspx?FamilyID=c69789e0-a4fa-4b2e-a6b5-3b3695825992

[CustomMessages]
de.dotnetfx20sp2lp_title=.NET Framework 2.0 SP2 Sprachpaket: Deutsch
es.dotnetfx20sp2lp_title=.NET Framework 2.0 SP2 paquete de idioma: Español

de.dotnetfx20sp2lp_size=3,4 MB - 5 MB
es.dotnetfx20sp2lp_size=3,4 MB - 4,9 MB

;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
de.dotnetfx20sp2lp_lcid=1031
es.dotnetfx20sp2lp_lcid=3082

de.dotnetfx20sp2lp_url=http://download.microsoft.com/download/0/b/1/0b175c8e-34bd-46c0-bfcd-af8d33770c58/netfx20sp2_x86de.exe
de.dotnetfx20sp2lp_url_x64=http://download.microsoft.com/download/4/e/c/4ec67a11-879d-4550-9c25-fd9ab4261b46/netfx20sp2_x64de.exe
es.dotnetfx20sp2lp_url=http://download.microsoft.com/download/2/5/f/25f168c7-ab97-4f04-8185-db316f85b714/netfx20sp2_x86es.exe
es.dotnetfx20sp2lp_url_x64=http://download.microsoft.com/download/0/7/a/07a33922-e5e4-444d-a67d-12726e1fbb90/netfx20sp2_x64es.exe

[Code]
procedure dotnetfx20sp2lp();
begin
	if (ActiveLanguage() <> 'en') then begin
		if (netfxspversion(NetFx20, CustomMessage('dotnetfx20sp2lp_lcid')) < 2) then
			AddProduct('dotnetfx20sp2' + GetArchitectureString() + '_' + ActiveLanguage() + '.exe',
				'/lang:enu /passive /norestart"',
				CustomMessage('dotnetfx20sp2lp_title'),
				CustomMessage('dotnetfx20sp2lp_size'),
				CustomMessage('dotnetfx20sp2lp_url' + GetArchitectureString()),
				false, false);
	end;
end;


Copy the version and revision header files located in the build directory to the SDK include directory.

[Setup]
; include either setup-sdk-win32.txt or setup-sdk-x64.txt
#include "setup-sdk-win32.txt"
;#include "setup-sdk-x64.txt"

[Types]
Name: full; Description: Full installation
Name: sdk; Description: SDK installation
Name: docs; Description: Documentation installation
Name: custom; Description: Custom installation; Flags: iscustom

[Components]
Name: sdk; Description: UniMRCP SDK (client, server and plugin development); Types: full sdk
Name: docs; Description: UniMRCP documentation; Types: full docs
Name: docs\design; Description: Design concepts; Types: full docs
Name: docs\api; Description: API reference; Types: full docs

[Files]
Source: {#= uni_src}\libs\apr\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\apr-toolkit\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mpf\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\message\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\control\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\resources\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-engine\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-signaling\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcpv2-transport\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\{#= release_dir}\lib\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr-util\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\sofia-sip\win32\libsofia-sip-ua\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\build\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\build\props\sdk\*.props; DestDir: {app}\props; Components: sdk; AfterInstall: SetProjectPath(ExpandConstant('{app}\props\unimrcpsdk.props'))
Source: {#= uni_src}\build\vsprops\sdk\*.vsprops; DestDir: {app}\vsprops; Components: sdk; AfterInstall: SetProjectPath(ExpandConstant('{app}\vsprops\unimrcpsdk.vsprops'))
Source: {#= uni_src}\docs\ea\*; DestDir: {app}\doc\ea; Components: docs/design; Flags: recursesubdirs
Source: {#= uni_src}\docs\dox\*; DestDir: {app}\doc\dox; Components: docs/api; Flags: recursesubdirs

[Icons]
Name: {group}\UniMRCP Docs\Design concepts; Filename: {app}\doc\ea\index.htm; Components: docs\design
Name: {group}\UniMRCP Docs\API; Filename: {app}\doc\dox\html\index.html; Components: docs\api
Name: {group}\Uninstall; Filename: {uninstallexe}

[Code]
procedure SetProjectPath(PropertySheetFile: String);
var
  Content: String;
begin
  LoadStringFromFile (PropertySheetFile, Content);
  StringChange (Content, 'C:\Program Files\UniMRCP', ExpandConstant('{app}'));
  SaveStringToFile (PropertySheetFile, Content, False);
end;

[Setup]
; include either setup-sdk-win32.txt or setup-sdk-x64.txt
#include "setup-sdk-win32.txt"
;#include "setup-sdk-x64.txt"

[Types]
Name: full; Description: Full installation
Name: sdk; Description: SDK installation
Name: docs; Description: Documentation installation
Name: custom; Description: Custom installation; Flags: iscustom

[Components]
Name: sdk; Description: UniMRCP SDK (client, server and plugin development); Types: full sdk
Name: docs; Description: UniMRCP documentation; Types: full docs
Name: docs\design; Description: Design concepts; Types: full docs
Name: docs\api; Description: API; Types: full docs

[Files]
Source: {#= uni_src}\libs\apr\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\apr-toolkit\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mpf\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\message\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\control\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\resources\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-engine\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-signaling\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcpv2-transport\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\{#= release_dir}\lib\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr-util\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\sofia-sip\win32\libsofia-sip-ua\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\build\props\sdk\*.props; DestDir: {app}\props; Components: sdk; AfterInstall: SetProjectPath(ExpandConstant('{app}\props\unimrcpsdk.props'))
Source: {#= uni_src}\build\vsprops\sdk\*.vsprops; DestDir: {app}\vsprops; Components: sdk; AfterInstall: SetProjectPath(ExpandConstant('{app}\vsprops\unimrcpsdk.vsprops'))
Source: {#= uni_src}\docs\ea\*; DestDir: {app}\doc\ea; Components: docs/design; Flags: recursesubdirs
Source: {#= uni_src}\docs\dox\*; DestDir: {app}\doc\dox; Components: docs/api; Flags: recursesubdirs

[Icons]
Name: {group}\UniMRCP Docs\Design concepts; Filename: {app}\doc\ea\index.htm; Components: docs\design
Name: {group}\UniMRCP Docs\API; Filename: {app}\doc\dox\html\index.html; Components: docs\api
Name: {group}\Uninstall; Filename: {uninstallexe}

[Code]
procedure SetProjectPath(PropertySheetFile: String);
var
  Content: String;
begin
  LoadStringFromFile (PropertySheetFile, Content);
  StringChange (Content, 'C:\Program Files\UniMRCP', ExpandConstant('{app}'));
  SaveStringToFile (PropertySheetFile, Content, False);
end;