Added options to not install some languages to the installer. Closes #50

#include "InstallDependancies.iss"

#define MyAppName "Bulk Crap Uninstaller"
#define MyAppNameShort "BCUninstaller"
#define MyAppPublisher "Marcin Szeniak"
#define MyAppURL "http://klocmansoftware.weebly.com/"
#define MyAppExeName "BCUninstaller.exe"
#define MyAppCopyright "Copyright 2017 Marcin Szeniak"

#define MyAppVersion "3.6.3.0"
#define MyAppVersionShort "3.6.3"

#include "Scripts\PortablePage.iss"
#include "Scripts\PortableIcons.iss"
#include "Scripts\Ngen.iss"

[Setup]
AppId={{f4fef76c-1aa9-441c-af7e-d27f58d898d1}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
UninstallDisplayIcon={app}\{#MyAppExeName}

WizardImageFile=bigImage.bmp
WizardSmallImageFile=smallImage.bmp
SetupIconFile=logo.ico

AllowNoIcons=yes
LicenseFile=Input\Licence.txt
OutputBaseFilename={#MyAppNameShort}_{#MyAppVersionShort}_setup

Compression=lzma2/ultra
SolidCompression=yes

;MinVersion default value: "0,5.0 (Windows 2000+) if Unicode Inno Setup, else 4.0,4.0 (Windows 95+)"
MinVersion=0,5.0
PrivilegesRequired=admin
ArchitecturesAllowed=x86 x64 ia64
ArchitecturesInstallIn64BitMode=x64 ia64

VersionInfoCompany={#MyAppPublisher}
;VersionInfoDescription=desc
VersionInfoCopyright={#MyAppCopyright}
VersionInfoProductName={#MyAppName}
VersionInfoProductVersion={#MyAppVersion}
VersionInfoProductTextVersion={#MyAppVersion}
VersionInfoVersion={#MyAppVersion}
VersionInfoTextVersion={#MyAppVersion}

[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "de"; MessagesFile: "compiler:Languages\German.isl"
Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl"

[Components]
Name: "main"; Description: "Main Files"; Types: full compact custom; Flags: fixed
Name: "lang"; Description: "Languages"; Types: full
Name: "lang\en"; Description: "English"; Types: full compact custom; Flags: fixed
Name: "lang\cs"; Description: "Czech"; Types: full
Name: "lang\de"; Description: "German"; Types: full
Name: "lang\es"; Description: "Spanish"; Types: full
Name: "lang\fr"; Description: "French"; Types: full
Name: "lang\hu"; Description: "Hungarian"; Types: full
Name: "lang\it"; Description: "Italian"; Types: full
Name: "lang\pl"; Description: "Polish"; Types: full
Name: "lang\pt"; Description: "Portuguese"; Types: full
Name: "lang\ru"; Description: "Russian"; Types: full
Name: "lang\sl"; Description: "Slovene"; Types: full

[Files]
Source: "Input\BCUninstaller.exe"; DestDir: "{app}"; Components: main; Flags: ignoreversion
Source: "Input\BCU_manual.html"; DestDir: "{app}"; Components: main; Flags: ignoreversion isreadme
Source: "Input\*"; DestDir: "{app}"; Components: main; Flags: ignoreversion

Source: "Input\cs\*"; DestDir: "{app}"; Components: lang\cs; Flags: ignoreversion
Source: "Input\de\*"; DestDir: "{app}"; Components: lang\de; Flags: ignoreversion
Source: "Input\es\*"; DestDir: "{app}"; Components: lang\es; Flags: ignoreversion
Source: "Input\fr\*"; DestDir: "{app}"; Components: lang\fr; Flags: ignoreversion
Source: "Input\hu\*"; DestDir: "{app}"; Components: lang\hu; Flags: ignoreversion
Source: "Input\it\*"; DestDir: "{app}"; Components: lang\it; Flags: ignoreversion
Source: "Input\pl\*"; DestDir: "{app}"; Components: lang\pl; Flags: ignoreversion
Source: "Input\pt\*"; DestDir: "{app}"; Components: lang\pt; Flags: ignoreversion
Source: "Input\ru\*"; DestDir: "{app}"; Components: lang\ru; Flags: ignoreversion
Source: "Input\sl\*"; DestDir: "{app}"; Components: lang\sl; Flags: ignoreversion

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

#include "InstallDependancies.iss"

#define MyAppName "Bulk Crap Uninstaller"
#define MyAppNameShort "BCUninstaller"
#define MyAppPublisher "Marcin Szeniak"
#define MyAppURL "http://klocmansoftware.weebly.com/"
#define MyAppExeName "BCUninstaller.exe"
#define MyAppCopyright "Copyright 2017 Marcin Szeniak"

#define MyAppVersion "3.6.3.0"
#define MyAppVersionShort "3.6.3"

#include "Scripts\PortablePage.iss"
#include "Scripts\PortableIcons.iss"
#include "Scripts\Ngen.iss"

[Setup]
AppId={{f4fef76c-1aa9-441c-af7e-d27f58d898d1}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
UninstallDisplayIcon={app}\{#MyAppExeName}

WizardImageFile=bigImage.bmp
WizardSmallImageFile=smallImage.bmp
SetupIconFile=logo.ico

AllowNoIcons=yes
LicenseFile=Input\Licence.txt
OutputBaseFilename={#MyAppNameShort}_{#MyAppVersionShort}_setup

Compression=lzma2/ultra
SolidCompression=yes

;MinVersion default value: "0,5.0 (Windows 2000+) if Unicode Inno Setup, else 4.0,4.0 (Windows 95+)"
MinVersion=0,5.0
PrivilegesRequired=admin
ArchitecturesAllowed=x86 x64 ia64
ArchitecturesInstallIn64BitMode=x64 ia64

VersionInfoCompany={#MyAppPublisher}
;VersionInfoDescription=desc
VersionInfoCopyright={#MyAppCopyright}
VersionInfoProductName={#MyAppName}
VersionInfoProductVersion={#MyAppVersion}
VersionInfoProductTextVersion={#MyAppVersion}
VersionInfoVersion={#MyAppVersion}
VersionInfoTextVersion={#MyAppVersion}

[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "de"; MessagesFile: "compiler:Languages\German.isl"
Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl"

[Files]
Source: "Input\BCUninstaller.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "Input\BCU_manual.html"; DestDir: "{app}"; Flags: ignoreversion isreadme
Source: "Input\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

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


Versioning

Versioning

[Setup]
AppName=LiveSPICE
AppVersion=0.5
AppPublisher=Dillon Sharlet
AppPublisherURL="www.livespice.org"
AppSupportURL="https://github.com/dsharlet/LiveSPICE/issues"
DefaultDirName={pf}\LiveSPICE
UninstallDisplayIcon="{app}\LiveSPICE.exe"
UninstallDisplayName=LiveSPICE
DefaultGroupName=LiveSPICE
SetupIconFile="LiveSPICE\LiveSPICE.ico"
Compression=lzma2
SolidCompression=yes
OutputBaseFilename=LiveSPICESetup
OutputDir=Setup

[Files]
Source: "LiveSPICE\bin\Release\LiveSPICE.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "LiveSPICE\bin\Release\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "Circuit\Components\*.xml"; DestDir: "{app}\Components"; Flags: onlyifdoesntexist

Source: "Tests\Circuits\Active 1stOrder Lowpass RC.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Passive 1stOrder Lowpass RC.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Bridge Rectifier.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Common Cathode Triode Amplifier.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Common Emitter Transistor Amplifier.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Op-Amp Model.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Boss SD1.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Boss SD1 (no buffer).schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Ibanez TS9.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Ibanez TS9 (no buffer).schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Marshall Blues Breaker.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist

[Run]
Filename: "{app}\LiveSPICE.exe"; Description: "Run LiveSPICE."; Flags: postinstall nowait

[Icons]
Name: "{group}\LiveSPICE"; Filename: "{app}\LiveSPICE.exe"

[Setup]
AppName=LiveSPICE
AppVersion=0.4
AppPublisher=Dillon Sharlet
AppPublisherURL="www.livespice.org"
AppSupportURL="https://github.com/dsharlet/LiveSPICE/issues"
DefaultDirName={pf}\LiveSPICE
UninstallDisplayIcon="{app}\LiveSPICE.exe"
UninstallDisplayName=LiveSPICE
DefaultGroupName=LiveSPICE
SetupIconFile="LiveSPICE\LiveSPICE.ico"
Compression=lzma2
SolidCompression=yes
OutputBaseFilename=LiveSPICESetup
OutputDir=Setup

[Files]
Source: "LiveSPICE\bin\Release\LiveSPICE.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "LiveSPICE\bin\Release\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "Circuit\Components\*.xml"; DestDir: "{app}\Components"; Flags: onlyifdoesntexist

Source: "Tests\Circuits\Active 1stOrder Lowpass RC.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Passive 1stOrder Lowpass RC.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Bridge Rectifier.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Common Cathode Triode Amplifier.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Common Emitter Transistor Amplifier.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Op-Amp Model.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Boss SD1.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Boss SD1 (no buffer).schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Ibanez TS9.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Ibanez TS9 (no buffer).schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist
Source: "Tests\Circuits\Marshall Blues Breaker.schx"; DestDir: "{userdocs}\LiveSPICE\Examples"; Flags: onlyifdoesntexist

[Run]
Filename: "{app}\LiveSPICE.exe"; Description: "Run LiveSPICE."; Flags: postinstall nowait

[Icons]
Name: "{group}\LiveSPICE"; Filename: "{app}\LiveSPICE.exe"


fixed a bug in looking for existing wallet.dat

; Coin Install Script
; Review the Code carefully when adopting to a new coin.
;
; written 2014 by fruor
; I'm not responsible for any setup/installer written with the help of this script
;
; place this file together with a .conf file for the users wallets in the folder
; where your windows binaries reside (the ones users can download)
; open the .iss file with Inno Setup and compile, output will go to a subfolder called \SETUP

; Choose a name that will match Program Files Folder, the Start Menu Items and the Uninstall Info
#define ProgramName "VeriCoin"

; Enter the Version Number of your binaries
#define VersionNumber "1.5.1"

; Enter the Name of the Folder created in \Appdata\Roaming where your binaries will place the user files, including wallet, conf file, blockchain info etc.
#define RoamingName "VeriCoin"

; Enter the Name of the main QT-File
#define QTexe "vericoin-qt.exe"

; Subfolder with additional files such as an extra folder for daemon
; Do not include \ symbol it will be added later
; If no subfolder is needed use #define SubDir ""
#define SubDir ""

; Enter the Name of the config file you wish to include
#define configfile "vericoin.conf"

; Enter the Name of the bootstrap file you wish to include
#define bootstrapfile "bootstrap.dat"

[Setup]
AppName={#ProgramName}
AppVersion={#VersionNumber}
DefaultDirName={pf32}\{#ProgramName}
DefaultGroupName={#ProgramName}
UninstallDisplayIcon={app}\{#QTexe}
Compression=lzma2
SolidCompression=yes
OutputDir=SETUP

[Dirs]
Name: "imageformats";
Name: "platforms";
Name: "fonts";

[Files]
Source: "*.exe"; DestDir: "{app}"; Components: main; Excludes: "*.iss"
Source: "*.dll"; DestDir: "{app}"; Components: main; Excludes: "*.iss"
Source: "fonts\*.ttf"; DestDir: "{app}\fonts"; Components: main;
Source: "imageformats\*"; DestDir: "{app}\imageformats"; Components: main;
Source: "platforms\*"; DestDir: "{app}\platforms"; Components: main;
Source: {#configfile}; DestDir: "{userappdata}\{#RoamingName}"; Components: config; Flags: uninsneveruninstall
Source: "fonts\Lato-Regular.TTF"; DestDir: "{fonts}"; FontInstall: "Lato"; Flags: onlyifdoesntexist uninsneveruninstall

[Icons]
Name: "{group}\{#ProgramName}"; Filename: "{app}\{#QTexe}"
Name: "{group}\Uninstall"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#ProgramName}"; Filename: "{app}\{#QTexe}"; WorkingDir: "{app}"; Tasks: desktopicon/common
Name: "{userdesktop}\{#ProgramName}"; Filename: "{app}\{#QTexe}"; WorkingDir: "{app}"; Tasks: desktopicon/user

[Tasks]
Name: desktopicon; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
Name: desktopicon\common; Description: "For all users"; GroupDescription: "Additional icons:"; Flags: exclusive
Name: desktopicon\user; Description: "For the current user only"; GroupDescription: "Additional icons:"; Flags: exclusive unchecked

[Components]
Name: main; Description: Main Program; Types: full compact custom; Flags: fixed
Name: config; Description: A config file including nodes to synchronize with the network; Types: full custom

[Code]
var
  ImportWalletFileName: String;
  Targetfile: String;

function WalletImport: Boolean;
begin
  Targetfile := ExpandConstant('{userappdata}\{#RoamingName}\wallet.dat');
  if not FileExists(Targetfile) then
    begin
      Targetfile := ExpandConstant('{app}\wallet.dat');
      if not FileExists(Targetfile) then
        begin
          if MsgBox('No Wallet has been found. Would you like to import an existing wallet? If you skip this step a wallet will be created once {#ProgramName} is started.',mbConfirmation,MB_YESNO) = IDYES then
            begin
              ImportWalletFileName := '';
              if GetOpenFileName('', ImportWalletFileName, '', 'wallet files (*.dat)|*.dat|All Files|*.*', 'dat') then
                begin
                  if not FileExists(Targetfile) then
                    begin
                      FileCopy (expandconstant(ImportWalletFileName), Targetfile, false);
                    end
                  else
                    begin
                      MsgBox('Wallet already exists, skipping import', mbInformation, MB_OK);
                    end;
                end;
            end;
        end;
    end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  Result := True;
  if CurPageID = wpFinished then
     Result := WalletImport;
end;

// UNINSTALL PREVIOUS VERSION //
function GetUninstallString(): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppName")}_is1');
  if sUnInstPath = '' then
    begin
      sUnInstPath := ExpandConstant('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppName")}_is1');
    end;
  sUnInstallString := '';
  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;

function UnInstallOldVersion(): Integer;
var
  sUnInstallString: String;
  iResultCode: Integer;
begin
// Return Values:
// 1 - uninstall string is empty
// 2 - error executing the UnInstallString
// 3 - successfully executed the UnInstallString

  // default return value
  Result := 0;

  // get the uninstall string of the old app
  sUnInstallString := GetUninstallString();
  if sUnInstallString <> '' then begin
    sUnInstallString := RemoveQuotes(sUnInstallString);
    if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
      Result := 3
    else
      Result := 2;
  end else
    Result := 1;
end;

function IsUpgrade(): Boolean;
begin
  Result := (GetUninstallString() <> '');
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if (CurStep=ssInstall) then
  begin
    if (IsUpgrade()) then
    begin
      UnInstallOldVersion();
    end;
  end;
end;
////////////////////////////////

[Run]
Filename: "{app}\{#QTexe}"; Flags: postinstall skipifsilent nowait

; Coin Install Script
; Review the Code carefully when adopting to a new coin.
;
; written 2014 by fruor
; I'm not responsible for any setup/installer written with the help of this script
;
; place this file together with a .conf file for the users wallets in the folder
; where your windows binaries reside (the ones users can download)
; open the .iss file with Inno Setup and compile, output will go to a subfolder called \SETUP

; Choose a name that will match Program Files Folder, the Start Menu Items and the Uninstall Info
#define ProgramName "VeriCoin"

; Enter the Version Number of your binaries
#define VersionNumber "1.5.1"

; Enter the Name of the Folder created in \Appdata\Roaming where your binaries will place the user files, including wallet, conf file, blockchain info etc.
#define RoamingName "VeriCoin"

; Enter the Name of the main QT-File
#define QTexe "vericoin-qt.exe"

; Subfolder with additional files such as an extra folder for daemon
; Do not include \ symbol it will be added later
; If no subfolder is needed use #define SubDir ""
#define SubDir ""

; Enter the Name of the config file you wish to include
#define configfile "vericoin.conf"

; Enter the Name of the bootstrap file you wish to include
#define bootstrapfile "bootstrap.dat"

[Setup]
AppName={#ProgramName}
AppVersion={#VersionNumber}
DefaultDirName={pf32}\{#ProgramName}
DefaultGroupName={#ProgramName}
UninstallDisplayIcon={app}\{#QTexe}
Compression=lzma2
SolidCompression=yes
OutputDir=SETUP

[Dirs]
Name: "imageformats";
Name: "platforms";
Name: "fonts";

[Files]
Source: "*.exe"; DestDir: "{app}"; Components: main; Excludes: "*.iss"
Source: "*.dll"; DestDir: "{app}"; Components: main; Excludes: "*.iss"
Source: "fonts\*.ttf"; DestDir: "{app}\fonts"; Components: main;
Source: "imageformats\*"; DestDir: "{app}\imageformats"; Components: main;
Source: "platforms\*"; DestDir: "{app}\platforms"; Components: main;
Source: {#configfile}; DestDir: "{userappdata}\{#RoamingName}"; Components: config; Flags: uninsneveruninstall
Source: "fonts\Lato-Regular.TTF"; DestDir: "{fonts}"; FontInstall: "Lato"; Flags: onlyifdoesntexist uninsneveruninstall

[Icons]
Name: "{group}\{#ProgramName}"; Filename: "{app}\{#QTexe}"
Name: "{group}\Uninstall"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#ProgramName}"; Filename: "{app}\{#QTexe}"; WorkingDir: "{app}"; Tasks: desktopicon/common
Name: "{userdesktop}\{#ProgramName}"; Filename: "{app}\{#QTexe}"; WorkingDir: "{app}"; Tasks: desktopicon/user

[Tasks]
Name: desktopicon; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
Name: desktopicon\common; Description: "For all users"; GroupDescription: "Additional icons:"; Flags: exclusive
Name: desktopicon\user; Description: "For the current user only"; GroupDescription: "Additional icons:"; Flags: exclusive unchecked

[Components]
Name: main; Description: Main Program; Types: full compact custom; Flags: fixed
Name: config; Description: A config file including nodes to synchronize with the network; Types: full custom

[Code]
var
  ImportWalletFileName: String;
  Targetfile: String;

function WalletImport: Boolean;
begin

  Targetfile := ExpandConstant('{userappdata}\{#RoamingName}\wallet.dat');
  if not FileExists(Targetfile) then
  begin
    if MsgBox('No Wallet has been found. Would you like to import an existing wallet? If you skip this step a wallet will be created once {#ProgramName} is started.',mbConfirmation,MB_YESNO) = IDYES then
        begin
          ImportWalletFileName := '';
          if GetOpenFileName('', ImportWalletFileName, '', 'wallet files (*.dat)|*.dat|All Files|*.*', 'dat') then
           begin
            if not FileExists(Targetfile) then
              begin
                FileCopy (expandconstant(ImportWalletFileName), Targetfile, false);
              end
              else
              begin
                MsgBox('Wallet already exists, skipping import', mbInformation, MB_OK);
              end;
            end;
        end;
  end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  Result := True;
  if CurPageID = wpFinished then
     Result := WalletImport;
end;

// UNINSTALL PREVIOUS VERSION //
function GetUninstallString(): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppName")}_is1');
  if sUnInstPath = '' then
    begin
      sUnInstPath := ExpandConstant('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppName")}_is1');
    end;
  sUnInstallString := '';
  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;

function UnInstallOldVersion(): Integer;
var
  sUnInstallString: String;
  iResultCode: Integer;
begin
// Return Values:
// 1 - uninstall string is empty
// 2 - error executing the UnInstallString
// 3 - successfully executed the UnInstallString

  // default return value
  Result := 0;

  // get the uninstall string of the old app
  sUnInstallString := GetUninstallString();
  if sUnInstallString <> '' then begin
    sUnInstallString := RemoveQuotes(sUnInstallString);
    if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
      Result := 3
    else
      Result := 2;
  end else
    Result := 1;
end;

function IsUpgrade(): Boolean;
begin
  Result := (GetUninstallString() <> '');
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if (CurStep=ssInstall) then
  begin
    if (IsUpgrade()) then
    begin
      UnInstallOldVersion();
    end;
  end;
end;
////////////////////////////////

[Run]
Filename: "{app}\{#QTexe}"; Flags: postinstall skipifsilent nowait


Updated installer script for version 2.0

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Guild Wars 2 Personal Assistant Overlay"
#define MyAppNameShort "GW2 Personal Assistant Overlay"
#define MyAppVersion "2.0"
#define MyAppPublisher "Samuel Hurne"
#define MyAppURL "http://samhurne.github.io/gw2pao/"
#define MyAppExeName "GW2PAO.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{7CEEC405-42EA-4C71-9CAA-3812E0CEF49A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\GW2PAO
DefaultGroupName=GW2 Personal Assistant Overlay
AllowNoIcons=yes
OutputBaseFilename=GW2PAO_Setup_{#MyAppVersion}
Compression=lzma
SolidCompression=yes
UninstallDisplayName=Guild Wars 2 Personal Assistant Overlay
UninstallDisplayIcon={app}\GW2PAO.exe

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
; No browser files:
Source: "..\GW2PAO\bin\Release_WithoutBrowser\AdjustedEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\AnetCopyright.txt"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\Dungeons.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\GW2PAO.exe"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\GW2PAO.exe.config"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\ItemDatabase.json"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\NLog.config"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\StandardEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\Worlds.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\WvWObjectives.xml"; DestDir: "{app}"; Flags: ignoreversion;
; Full install files:
Source: "..\GW2PAO\bin\Release\GW2PAO.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\AdjustedEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\AnetCopyright.txt"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\avcodec-53.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\avformat-53.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\avutil-51.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Awesomium.Core.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\awesomium.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Awesomium.Windows.Controls.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\awesomium_process"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Dungeons.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\GW2PAO.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\GW2PAO.exe.config"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\icudt.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\inspector.pak"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\ItemDatabase.json"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\libEGL.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\libGLESv2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\NLog.config"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\StandardEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Worlds.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\WvWObjectives.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\xinput9_1_0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser

[Icons]
Name: "{group}\{#MyAppNameShort}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppNameShort}}"; Filename: "{#MyAppURL}"
Name: "{commondesktop}\{#MyAppNameShort}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppNameShort}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

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

[Components]
Name: "Browser"; Description: "Include Browser Feature"; Types: full

[Dirs]
Name: "{app}\Settings"; Permissions: users-full
Name: "{app}\Logs"; Permissions: users-full
Name: "{app}\Cache"; Flags: uninsalwaysuninstall; Components: Browser; Permissions: users-full

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Guild Wars 2 Personal Assistant Overlay"
#define MyAppNameShort "GW2 Personal Assistant Overlay"
#define MyAppVersion "1.6"
#define MyAppPublisher "Samuel Hurne"
#define MyAppURL "http://samhurne.github.io/gw2pao/"
#define MyAppExeName "GW2PAO.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{7CEEC405-42EA-4C71-9CAA-3812E0CEF49A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\GW2PAO
DefaultGroupName=GW2 Personal Assistant Overlay
AllowNoIcons=yes
OutputBaseFilename=GW2PAO_Setup_{#MyAppVersion}
Compression=lzma
SolidCompression=yes
UninstallDisplayName=Guild Wars 2 Personal Assistant Overlay
UninstallDisplayIcon={app}\GW2PAO.exe

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
; No browser files:
Source: "..\GW2PAO\bin\Release_WithoutBrowser\AdjustedEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\AnetCopyright.txt"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\Dungeons.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\GW2PAO.exe"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\GW2PAO.exe.config"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\ItemDatabase.json"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\NLog.config"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\StandardEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\Worlds.xml"; DestDir: "{app}"; Flags: ignoreversion;
Source: "..\GW2PAO\bin\Release_WithoutBrowser\WvWObjectives.xml"; DestDir: "{app}"; Flags: ignoreversion;
; Full install files:
Source: "..\GW2PAO\bin\Release\GW2PAO.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\AdjustedEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\AnetCopyright.txt"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\avcodec-53.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\avformat-53.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\avutil-51.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Awesomium.Core.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\awesomium.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Awesomium.Windows.Controls.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\awesomium_process"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Dungeons.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\GW2PAO.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\GW2PAO.exe.config"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\icudt.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\inspector.pak"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\ItemDatabase.json"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\libEGL.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\libGLESv2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\NLog.config"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\StandardEventTimeTable.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\Worlds.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\WvWObjectives.xml"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser
Source: "..\GW2PAO\bin\Release\xinput9_1_0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: Browser

[Icons]
Name: "{group}\{#MyAppNameShort}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppNameShort}}"; Filename: "{#MyAppURL}"
Name: "{commondesktop}\{#MyAppNameShort}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppNameShort}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

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

[Components]
Name: "Browser"; Description: "Include Browser Feature"; Types: full

[Dirs]
Name: "{app}\Settings"; Permissions: users-full
Name: "{app}\Logs"; Permissions: users-full
Name: "{app}\Cache"; Flags: uninsalwaysuninstall; Components: Browser; Permissions: users-full


delete output/*.pyc on uninstall

delete output/*.pyc on uninstall

git-svn-id: 7746e1be614c04306162a6afe133859c0e9253b7@763 34294538-1d18-489e-82e9-bb8ff975a0eb

; This script was first created by ISTool
; http://www.lerstad.com/istool/

#define VERSION          "0.1.9"

[Setup]
OutputBaseFilename=bakefile-{#VERSION}-setup
AppName=Bakefile
AppVerName=Bakefile {#VERSION}

ChangesAssociations=false
AlwaysShowComponentsList=true
SourceDir=.
DefaultDirName={pf}\Bakefile

DefaultGroupName=Bakefile
AllowNoIcons=true
UninstallStyle=modern

OutputDir=.

Compression=lzma

WindowShowCaption=true
WindowStartMaximized=false
FlatComponentsList=true
WindowResizable=false
ShowTasksTreeLines=false
DisableProgramGroupPage=true
LicenseFile=COPYING

SolidCompression=true
InternalCompressLevel=max
ShowLanguageDialog=yes
[Files]
Source: src\*; DestDir: {app}\src; Flags: recursesubdirs; Components: base
Source: rules\*; DestDir: {app}\rules; Flags: recursesubdirs; Components: base
Source: presets\*; DestDir: {app}\presets; Flags: recursesubdirs; Components: base
Source: output\*; DestDir: {app}\output; Flags: recursesubdirs; Components: base
Source: tests\*; DestDir: {app}\tests; Flags: recursesubdirs; Components: tests
Source: doc\*; DestDir: {app}\doc; Flags: recursesubdirs; Components: doc
Source: ..\minipython\*; DestDir: {app}\src; Flags: recursesubdirs; Components: python; Excludes: *.pyc
Source: README; DestDir: {app}; Components: base
Source: NEWS; DestDir: {app}; Components: base; AfterInstall: InstallSetupPath
Source: THANKS; DestDir: {app}; Components: base
Source: COPYING; DestDir: {app}; Components: base
Source: AUTHORS; DestDir: {app}; Components: base

[Registry]

[Icons]

[Run]

[_ISTool]
EnableISX=true
UseAbsolutePaths=false

Use7zip=false
[Dirs]

[_ISToolPreCompile]

[Components]
Name: base; Description: Bakefile code; Flags: fixed; Types: custom compact full
Name: python; Description: Python runtime; Flags: fixed; Types: custom compact full
Name: doc; Description: Documentation; Types: custom full
Name: tests; Description: Tests and examples; Types: custom full

[Messages]
BeveledLabel=Bakefile

[UninstallDelete]
Name: {app}\src; Type: filesandordirs
Name: {app}\output; Type: filesandordirs
[Tasks]
Name: addpath; Description: Add Bakefile to PATH environment variable (may not work); Flags: unchecked
[Code]
// -----------------------------------------------------------------
//                    code for changing PATH
// -----------------------------------------------------------------

//
// Inno Setup Extensions Knowledge Base
// Article 44 - Native ISX procedures for PATH modification
// http://www13.brinkster.com/vincenzog/isxart.asp?idart=44
// Author: Thomas Vedel
//

// Version log:
// 03/31/2003: Initial release (thv@lr.dk)

const
  // Modification method
  pmAddToBeginning = $1;      // Add dir to beginning of Path
  pmAddToEnd = $2;            // Add dir to end of Path
  pmAddAllways = $4;          // Add also if specified dir is already included in existing path
  pmAddOnlyIfDirExists = $8;  // Add only if specified dir actually exists
  pmRemove = $10;             // Remove dir from path
  pmRemoveSubdirsAlso = $20;  // Remove dir and all subdirs from path

  // Scope
  psCurrentUser = 1;          // Modify path for current user
  psAllUsers = 2;             // Modify path for all users

  // Error results
  mpOK = 0;                   // No errors
  mpMissingRights = -1;       // User has insufficient rights
  mpAutoexecNoWriteacc = -2;  // Autoexec can not be written (may be readonly)
  mpBothAddAndRemove = -3;    // User has specified that dir should both be removed from and added to path

{ Helper procedure: Split a path environment variable into individual dirnames }
procedure SplitPath(Path: string; var Dirs: TStringList);
var
  pos: integer;
  s: string;
begin
  Dirs.Clear;
  s := '';
  pos := 1;
  while (pos<=Length(Path)) do
  begin
    if (Path[pos]<>';') then
      s := s + Path[pos];
    if ((Path[pos]=';') or (pos=Length(Path))) then
    begin
      s := Trim(s);
      s := RemoveQuotes(s);
      s := Trim(s);
      if (s <> '') then
        Dirs.Add(s);
      s := '';
    end;
    Pos := Pos + 1;
  end;
end; // procedure SplitPath

{ Helper procedure: Concatenate individual dirnames into a path environment variable }
procedure ConcatPath(Dirs: TStringList; Quotes: boolean; var Path: string);
var
  Index, MaxIndex: integer;
  s: string;
begin
  MaxIndex := Dirs.Count-1;
  Path := '';
  for Index := 0 to MaxIndex do
  begin
    s := Dirs.Strings[Index];
    if ((Quotes) and (pos(' ',s) > 0)) then
      s := AddQuotes(s);
    Path := Path + s;
    if (Index < MaxIndex) then
      Path := Path + ';'
  end;
end; // procedure ConcatPath

{ Helper function: Modifies path environment string }
procedure ModifyPathString(OldPath, DirName: string; Method: integer; Quotes: boolean; var ResultPath: string);
var
  Dirs: TStringList;
  DirNotInPath: Boolean;
  i: integer;
begin
  // Create Dirs variable
  Dirs := TStringList.Create;

  // Remove quotes form DirName
  DirName := Trim(DirName);
  DirName := RemoveQuotes(DirName);
  DirName := Trim(DirName);

  // Split old path in individual directory names
  SplitPath(OldPath, Dirs);

  // Check if dir is allready in path
  DirNotInPath := True;
  for i:=Dirs.Count-1 downto 0 do
  begin
    if (uppercase(Dirs.Strings[i]) = uppercase(DirName)) then
      DirNotInPath := False;
  end;

  // Should dir be removed from existing Path?
  if ((Method and (pmRemove or pmRemoveSubdirsAlso)) > 0) then
  begin
    for i:=Dirs.Count-1 downto 0 do
    begin
      if (((Method and pmRemoveSubdirsAlso) > 0) and (pos(uppercase(DirName)+'\', uppercase(Dirs.Strings[i])) = 1)) or
         (((Method and (pmRemove) or (pmRemoveSubdirsAlso)) > 0) and (uppercase(DirName) = uppercase(Dirs.Strings[i])))
      then
        Dirs.Delete(i);
    end;
  end;

  // Should dir be added to existing Path?
  if ((Method and (pmAddToBeginning or pmAddToEnd)) > 0) then
  begin
    // Add dir to path
    if (((Method and pmAddAllways) > 0) or DirNotInPath) then
    begin
      // Dir is not in path allready or should be added anyway
      if (((Method and pmAddOnlyIfDirExists) = 0) or (DirExists(DirName))) then
      begin
        // Dir actually exsists or should be added anyway
        if ((Method and pmAddToBeginning) > 0) then
          Dirs.Insert(0, DirName)
        else
          Dirs.Append(DirName);
      end;
    end;
  end;

  // Concatenate directory names into one single path variable
  ConcatPath(Dirs, Quotes, ResultPath);
  // Finally free Dirs object
  Dirs.Free;
end; // ModifyPathString

{ Helper function: Modify path on Windows 9x }
function ModifyPath9x(DirName: string; Method: integer): integer;
var
  AutoexecLines: TStringList;
  ActualLine: String;
  PathLineNos: TStringList;
  FirstPathLineNo: Integer;
  OldPath, ResultPath: String;
  LineNo, CharNo, Index: integer;

  TempString: String;
begin
  // Expect everything to be OK
  result := mpOK;

  // Create stringslists
  AutoexecLines := TStringList.Create;
  PathLineNos := TStringList.Create;

  // Read existing path
  OldPath := '';
  LoadStringFromFile('c:\Autoexec.bat', TempString);
  AutoexecLines.Text := TempString;
  PathLineNos.Clear;
  // Read Autoexec line by line
  for LineNo := 0 to AutoexecLines.Count - 1 do begin
    ActualLine := AutoexecLines.Strings[LineNo];
    // Check if line starts with "PATH=" after first stripping spaces and other "fill-chars"
    if Pos('=', ActualLine) > 0 then
    begin
      for CharNo := Pos('=', ActualLine)-1 downto 1 do
        if (ActualLine[CharNo]=' ') or (ActualLine[CharNo]=#9) then
          Delete(ActualLine, CharNo, 1);
      if Pos('@', ActualLine) = 1 then
        Delete(ActualLine, 1, 1);
      if (Pos('PATH=', uppercase(ActualLine))=1) or (Pos('SETPATH=', uppercase(ActualLine))=1) then
      begin
        // Remove 'PATH=' and add path to "OldPath" variable
        Delete(ActualLine, 1, pos('=', ActualLine));
        // Check if an earlier PATH variable is referenced, but there has been no previous PATH defined in Autoexec
        if (pos('%PATH%',uppercase(ActualLine))>0) and (PathLineNos.Count=0) then
          OldPath := ExpandConstant('{win}') + ';' + ExpandConstant('{win}')+'\COMMAND';
        if (pos('%PATH%',uppercase(ActualLine))>0) then
        begin
          ActualLine := Copy(ActualLine, 1, pos('%PATH%',uppercase(ActualLine))-1) +
                        OldPath +
                        Copy(ActualLine, pos('%PATH%',uppercase(ActualLine))+6, Length(ActualLine));
        end;
        OldPath := ActualLine;

        // Update list of line numbers holding path variables
        PathLineNos.Add(IntToStr(LineNo));
      end;
    end;
  end;

  // Save first line number in Autoexec.bat which modifies path environment variable
  if PathLineNos.Count > 0 then
    FirstPathLineNo := StrToInt(PathLineNos.Strings[0])
  else
    FirstPathLineNo := 0;

  // Modify path
  ModifyPathString(OldPath, DirName, Method, True, ResultPath);

  // Write Modified path back to Autoexec.bat
  // First delete all existing path references from Autoexec.bat
  Index := PathLineNos.Count-1;
  while (Index>=0) do
  begin
    AutoexecLines.Delete(StrToInt(PathLineNos.Strings[Index]));
    Index := Index-1;
  end;
  // Then insert new path variable into Autoexec.bat
  AutoexecLines.Insert(FirstPathLineNo, '@PATH='+ResultPath);
  // Delete old Autoexec.bat from disk
  if not DeleteFile('c:\Autoexec.bat') then
    result := mpAutoexecNoWriteAcc;
  Sleep(500);
  // And finally write Autoexec.bat back to disk
  if not (result=mpAutoexecNoWriteAcc) then
    SaveStringToFile('c:\Autoexec.bat', AutoexecLines.Text, false);

  // Free stringlists
  PathLineNos.Free;
  AutoexecLines.Free;
end; // ModifyPath9x

{ Helper function: Modify path on Windows NT, 2000 and XP }
function ModifyPathNT(DirName: string; Method, Scope: integer): integer;
var
  RegRootKey: integer;
  RegSubKeyName: string;
  RegValueName: string;
  OldPath, ResultPath: string;
  OK: boolean;
begin
  // Expect everything to be OK
  result := mpOK;

  // Initialize registry key and value names to reflect if changes should be global or local to current user only
  case Scope of
    psCurrentUser:
      begin
        RegRootKey := HKEY_CURRENT_USER;
        RegSubKeyName := 'Environment';
        RegValueName := 'Path';
      end;
    psAllUsers:
      begin
        RegRootKey := HKEY_LOCAL_MACHINE;
        RegSubKeyName := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
        RegValueName := 'Path';
      end;
  end;

  // Read current path value from registry
  OK := RegQueryStringValue(RegRootKey, RegSubKeyName, RegValueName, OldPath);
  if not OK then
  begin
    result := mpMissingRights;
    Exit;
  end;

  // Modify path
  ModifyPathString(OldPath, DirName, Method, False, ResultPath);

  // Write new path value to registry
  if not RegWriteStringValue(RegRootKey, RegSubKeyName, RegValueName, ResultPath) then
  begin
    result := mpMissingRights;
    Exit;

  end;
end; // ModifyPathNT

{ Main function: Modify path }
function ModifyPath(Path: string; Method, Scope: integer): integer;
begin
  // Check if both add and remove has been specified (= error!)
  if (Method and (pmAddToBeginning or pmAddToEnd) and (pmRemove or pmRemoveSubdirsAlso)) > 0 then
  begin
    result := mpBothAddAndRemove;
    Exit;
  end;

  // Perform directory constant expansion
  Path := ExpandConstantEx(Path, ' ', ' ');

  // Test if Win9x
  if InstallOnThisVersion('4,0','0,0') = irInstall then
    ModifyPath9x(Path, Method);

  // Test if WinNT, 2000 or XP
  if InstallOnThisVersion('0,4','0,0') = irInstall then
    ModifyPathNT(Path, Method, Scope);
end; // ModifyPath

// -----------------------------------------------------------------
//                     install script hooks
// -----------------------------------------------------------------

procedure SetupPATH;
var
  p : string;
  scope : integer;
begin
  p:= ExpandConstant('{app}\src');
  if IsAdminLoggedOn then
    scope:= psAllUsers
  else
    scope:= psCurrentUser;
  ModifyPath(p, pmAddToEnd, scope);
end;

procedure InstallSetupPath;
begin
    if ShouldProcessEntry('', 'addpath') = srYes then
		SetupPATH;
end;

; This script was first created by ISTool
; http://www.lerstad.com/istool/

#define VERSION          "0.1.9"

[Setup]
OutputBaseFilename=bakefile-{#VERSION}-setup
AppName=Bakefile
AppVerName=Bakefile {#VERSION}

ChangesAssociations=false
AlwaysShowComponentsList=true
SourceDir=.
DefaultDirName={pf}\Bakefile

DefaultGroupName=Bakefile
AllowNoIcons=true
UninstallStyle=modern

OutputDir=.

Compression=lzma

WindowShowCaption=true
WindowStartMaximized=false
FlatComponentsList=true
WindowResizable=false
ShowTasksTreeLines=false
DisableProgramGroupPage=true
LicenseFile=COPYING

SolidCompression=true
InternalCompressLevel=max
ShowLanguageDialog=yes
[Files]
Source: src\*; DestDir: {app}\src; Flags: recursesubdirs; Components: base
Source: rules\*; DestDir: {app}\rules; Flags: recursesubdirs; Components: base
Source: presets\*; DestDir: {app}\presets; Flags: recursesubdirs; Components: base
Source: output\*; DestDir: {app}\output; Flags: recursesubdirs; Components: base
Source: tests\*; DestDir: {app}\tests; Flags: recursesubdirs; Components: tests
Source: doc\*; DestDir: {app}\doc; Flags: recursesubdirs; Components: doc
Source: ..\minipython\*; DestDir: {app}\src; Flags: recursesubdirs; Components: python; Excludes: *.pyc
Source: README; DestDir: {app}; Components: base
Source: NEWS; DestDir: {app}; Components: base; AfterInstall: InstallSetupPath
Source: THANKS; DestDir: {app}; Components: base
Source: COPYING; DestDir: {app}; Components: base
Source: AUTHORS; DestDir: {app}; Components: base

[Registry]

[Icons]

[Run]

[_ISTool]
EnableISX=true
UseAbsolutePaths=false

Use7zip=false
[Dirs]

[_ISToolPreCompile]

[Components]
Name: base; Description: Bakefile code; Flags: fixed; Types: custom compact full
Name: python; Description: Python runtime; Flags: fixed; Types: custom compact full
Name: doc; Description: Documentation; Types: custom full
Name: tests; Description: Tests and examples; Types: custom full

[Messages]
BeveledLabel=Bakefile

[UninstallDelete]
Name: {app}\src; Type: filesandordirs
[Tasks]
Name: addpath; Description: Add Bakefile to PATH environment variable (may not work); Flags: unchecked
[Code]
// -----------------------------------------------------------------
//                    code for changing PATH
// -----------------------------------------------------------------

//
// Inno Setup Extensions Knowledge Base
// Article 44 - Native ISX procedures for PATH modification
// http://www13.brinkster.com/vincenzog/isxart.asp?idart=44
// Author: Thomas Vedel
//

// Version log:
// 03/31/2003: Initial release (thv@lr.dk)

const
  // Modification method
  pmAddToBeginning = $1;      // Add dir to beginning of Path
  pmAddToEnd = $2;            // Add dir to end of Path
  pmAddAllways = $4;          // Add also if specified dir is already included in existing path
  pmAddOnlyIfDirExists = $8;  // Add only if specified dir actually exists
  pmRemove = $10;             // Remove dir from path
  pmRemoveSubdirsAlso = $20;  // Remove dir and all subdirs from path

  // Scope
  psCurrentUser = 1;          // Modify path for current user
  psAllUsers = 2;             // Modify path for all users

  // Error results
  mpOK = 0;                   // No errors
  mpMissingRights = -1;       // User has insufficient rights
  mpAutoexecNoWriteacc = -2;  // Autoexec can not be written (may be readonly)
  mpBothAddAndRemove = -3;    // User has specified that dir should both be removed from and added to path

{ Helper procedure: Split a path environment variable into individual dirnames }
procedure SplitPath(Path: string; var Dirs: TStringList);
var
  pos: integer;
  s: string;
begin
  Dirs.Clear;
  s := '';
  pos := 1;
  while (pos<=Length(Path)) do
  begin
    if (Path[pos]<>';') then
      s := s + Path[pos];
    if ((Path[pos]=';') or (pos=Length(Path))) then
    begin
      s := Trim(s);
      s := RemoveQuotes(s);
      s := Trim(s);
      if (s <> '') then
        Dirs.Add(s);
      s := '';
    end;
    Pos := Pos + 1;
  end;
end; // procedure SplitPath

{ Helper procedure: Concatenate individual dirnames into a path environment variable }
procedure ConcatPath(Dirs: TStringList; Quotes: boolean; var Path: string);
var
  Index, MaxIndex: integer;
  s: string;
begin
  MaxIndex := Dirs.Count-1;
  Path := '';
  for Index := 0 to MaxIndex do
  begin
    s := Dirs.Strings[Index];
    if ((Quotes) and (pos(' ',s) > 0)) then
      s := AddQuotes(s);
    Path := Path + s;
    if (Index < MaxIndex) then
      Path := Path + ';'
  end;
end; // procedure ConcatPath

{ Helper function: Modifies path environment string }
procedure ModifyPathString(OldPath, DirName: string; Method: integer; Quotes: boolean; var ResultPath: string);
var
  Dirs: TStringList;
  DirNotInPath: Boolean;
  i: integer;
begin
  // Create Dirs variable
  Dirs := TStringList.Create;

  // Remove quotes form DirName
  DirName := Trim(DirName);
  DirName := RemoveQuotes(DirName);
  DirName := Trim(DirName);

  // Split old path in individual directory names
  SplitPath(OldPath, Dirs);

  // Check if dir is allready in path
  DirNotInPath := True;
  for i:=Dirs.Count-1 downto 0 do
  begin
    if (uppercase(Dirs.Strings[i]) = uppercase(DirName)) then
      DirNotInPath := False;
  end;

  // Should dir be removed from existing Path?
  if ((Method and (pmRemove or pmRemoveSubdirsAlso)) > 0) then
  begin
    for i:=Dirs.Count-1 downto 0 do
    begin
      if (((Method and pmRemoveSubdirsAlso) > 0) and (pos(uppercase(DirName)+'\', uppercase(Dirs.Strings[i])) = 1)) or
         (((Method and (pmRemove) or (pmRemoveSubdirsAlso)) > 0) and (uppercase(DirName) = uppercase(Dirs.Strings[i])))
      then
        Dirs.Delete(i);
    end;
  end;

  // Should dir be added to existing Path?
  if ((Method and (pmAddToBeginning or pmAddToEnd)) > 0) then
  begin
    // Add dir to path
    if (((Method and pmAddAllways) > 0) or DirNotInPath) then
    begin
      // Dir is not in path allready or should be added anyway
      if (((Method and pmAddOnlyIfDirExists) = 0) or (DirExists(DirName))) then
      begin
        // Dir actually exsists or should be added anyway
        if ((Method and pmAddToBeginning) > 0) then
          Dirs.Insert(0, DirName)
        else
          Dirs.Append(DirName);
      end;
    end;
  end;

  // Concatenate directory names into one single path variable
  ConcatPath(Dirs, Quotes, ResultPath);
  // Finally free Dirs object
  Dirs.Free;
end; // ModifyPathString

{ Helper function: Modify path on Windows 9x }
function ModifyPath9x(DirName: string; Method: integer): integer;
var
  AutoexecLines: TStringList;
  ActualLine: String;
  PathLineNos: TStringList;
  FirstPathLineNo: Integer;
  OldPath, ResultPath: String;
  LineNo, CharNo, Index: integer;

  TempString: String;
begin
  // Expect everything to be OK
  result := mpOK;

  // Create stringslists
  AutoexecLines := TStringList.Create;
  PathLineNos := TStringList.Create;

  // Read existing path
  OldPath := '';
  LoadStringFromFile('c:\Autoexec.bat', TempString);
  AutoexecLines.Text := TempString;
  PathLineNos.Clear;
  // Read Autoexec line by line
  for LineNo := 0 to AutoexecLines.Count - 1 do begin
    ActualLine := AutoexecLines.Strings[LineNo];
    // Check if line starts with "PATH=" after first stripping spaces and other "fill-chars"
    if Pos('=', ActualLine) > 0 then
    begin
      for CharNo := Pos('=', ActualLine)-1 downto 1 do
        if (ActualLine[CharNo]=' ') or (ActualLine[CharNo]=#9) then
          Delete(ActualLine, CharNo, 1);
      if Pos('@', ActualLine) = 1 then
        Delete(ActualLine, 1, 1);
      if (Pos('PATH=', uppercase(ActualLine))=1) or (Pos('SETPATH=', uppercase(ActualLine))=1) then
      begin
        // Remove 'PATH=' and add path to "OldPath" variable
        Delete(ActualLine, 1, pos('=', ActualLine));
        // Check if an earlier PATH variable is referenced, but there has been no previous PATH defined in Autoexec
        if (pos('%PATH%',uppercase(ActualLine))>0) and (PathLineNos.Count=0) then
          OldPath := ExpandConstant('{win}') + ';' + ExpandConstant('{win}')+'\COMMAND';
        if (pos('%PATH%',uppercase(ActualLine))>0) then
        begin
          ActualLine := Copy(ActualLine, 1, pos('%PATH%',uppercase(ActualLine))-1) +
                        OldPath +
                        Copy(ActualLine, pos('%PATH%',uppercase(ActualLine))+6, Length(ActualLine));
        end;
        OldPath := ActualLine;

        // Update list of line numbers holding path variables
        PathLineNos.Add(IntToStr(LineNo));
      end;
    end;
  end;

  // Save first line number in Autoexec.bat which modifies path environment variable
  if PathLineNos.Count > 0 then
    FirstPathLineNo := StrToInt(PathLineNos.Strings[0])
  else
    FirstPathLineNo := 0;

  // Modify path
  ModifyPathString(OldPath, DirName, Method, True, ResultPath);

  // Write Modified path back to Autoexec.bat
  // First delete all existing path references from Autoexec.bat
  Index := PathLineNos.Count-1;
  while (Index>=0) do
  begin
    AutoexecLines.Delete(StrToInt(PathLineNos.Strings[Index]));
    Index := Index-1;
  end;
  // Then insert new path variable into Autoexec.bat
  AutoexecLines.Insert(FirstPathLineNo, '@PATH='+ResultPath);
  // Delete old Autoexec.bat from disk
  if not DeleteFile('c:\Autoexec.bat') then
    result := mpAutoexecNoWriteAcc;
  Sleep(500);
  // And finally write Autoexec.bat back to disk
  if not (result=mpAutoexecNoWriteAcc) then
    SaveStringToFile('c:\Autoexec.bat', AutoexecLines.Text, false);

  // Free stringlists
  PathLineNos.Free;
  AutoexecLines.Free;
end; // ModifyPath9x

{ Helper function: Modify path on Windows NT, 2000 and XP }
function ModifyPathNT(DirName: string; Method, Scope: integer): integer;
var
  RegRootKey: integer;
  RegSubKeyName: string;
  RegValueName: string;
  OldPath, ResultPath: string;
  OK: boolean;
begin
  // Expect everything to be OK
  result := mpOK;

  // Initialize registry key and value names to reflect if changes should be global or local to current user only
  case Scope of
    psCurrentUser:
      begin
        RegRootKey := HKEY_CURRENT_USER;
        RegSubKeyName := 'Environment';
        RegValueName := 'Path';
      end;
    psAllUsers:
      begin
        RegRootKey := HKEY_LOCAL_MACHINE;
        RegSubKeyName := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
        RegValueName := 'Path';
      end;
  end;

  // Read current path value from registry
  OK := RegQueryStringValue(RegRootKey, RegSubKeyName, RegValueName, OldPath);
  if not OK then
  begin
    result := mpMissingRights;
    Exit;
  end;

  // Modify path
  ModifyPathString(OldPath, DirName, Method, False, ResultPath);

  // Write new path value to registry
  if not RegWriteStringValue(RegRootKey, RegSubKeyName, RegValueName, ResultPath) then
  begin
    result := mpMissingRights;
    Exit;

  end;
end; // ModifyPathNT

{ Main function: Modify path }
function ModifyPath(Path: string; Method, Scope: integer): integer;
begin
  // Check if both add and remove has been specified (= error!)
  if (Method and (pmAddToBeginning or pmAddToEnd) and (pmRemove or pmRemoveSubdirsAlso)) > 0 then
  begin
    result := mpBothAddAndRemove;
    Exit;
  end;

  // Perform directory constant expansion
  Path := ExpandConstantEx(Path, ' ', ' ');

  // Test if Win9x
  if InstallOnThisVersion('4,0','0,0') = irInstall then
    ModifyPath9x(Path, Method);

  // Test if WinNT, 2000 or XP
  if InstallOnThisVersion('0,4','0,0') = irInstall then
    ModifyPathNT(Path, Method, Scope);
end; // ModifyPath

// -----------------------------------------------------------------
//                     install script hooks
// -----------------------------------------------------------------

procedure SetupPATH;
var
  p : string;
  scope : integer;
begin
  p:= ExpandConstant('{app}\src');
  if IsAdminLoggedOn then
    scope:= psAllUsers
  else
    scope:= psCurrentUser;
  ModifyPath(p, pmAddToEnd, scope);
end;

procedure InstallSetupPath;
begin
    if ShouldProcessEntry('', 'addpath') = srYes then
		SetupPATH;
end;


Fixed all of the aesthetics of the W Installer

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "KanColleTool"
#define MyAppVersion "0.3"
#define MyAppPublisher "MacaroniCode"
#define MyAppURL "http://kancolletool.github.io/"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{E4E165A9-C85C-4531-B1DC-B6F696298DA8}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
OutputBaseFilename=KanColleTool-Setup
Compression=lzma
SolidCompression=yes
SourceDir=..\..\dist\KanColleTool
OutputDir=..

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

[Files]
Source: "*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\KanColleTool"; Filename: "{app}\KanColleTool.exe"
Name: "{group}\KCT Viewer"; Filename: "{app}\KCTViewer.exe"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "KanColleTool"
#define MyAppVersion "0.3"
#define MyAppPublisher "MacaroniCode"
#define MyAppURL "http://kancolletool.github.io/"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{E4E165A9-C85C-4531-B1DC-B6F696298DA8}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
OutputBaseFilename=KanColleTool-Setup
Compression=lzma
SolidCompression=yes
SourceDir=..\..\dist\KanColleTool
OutputDir=..

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

[Files]
Source: "*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"


update script for Inno Setup 5.4.3

update script for Inno Setup 5.4.3

git-svn-id: 756506b3b0ea8c31733a8f0a5bb416c7e269da3d@683 28bd50df-7adb-d945-0439-6e466c6a13cc

;* Notepad2-mod - Installer script
;*
;* Copyright (C) 2010-2011 XhmikosR
;*
;* This file is part of Notepad2-mod.
;*
;* See License.txt for details.

; Requirements:
; Inno Setup v5.4.2(+): http://www.jrsoftware.org/isdl.php

; $Id$

;#define ICL12
;#define VS2010
;#define WDK

; Preprocessor related stuff
#if VER < 0x05040300
  #error Update your Inno Setup version
#endif

#if !defined(ICL12) && !defined(VS2010) && !defined(WDK)
  #error You need to define ICL12 or VS2010 or WDK first
#endif

#if defined(ICL12) && (defined(VS2010) || defined(WDK))
  #error You can't define ICL12 and at the same time
#endif

#if defined(VS2010) && ( defined(ICL12) || defined(WDK))
  #error You can't define WDK and at the same time
#endif

#if defined(WDK) && (defined(ICL12) || defined(VS2010))
  #error You can't use two defines at the same time
#endif

#if defined(ICL12)
  #define compiler "ICL12"
  #define sse2_required
#elif defined(VS2010)
  #define compiler "VS2010"
#elif defined(WDK)
  #define compiler "WDK"
#endif

#define bindir       "..\bin\" + compiler

#ifnexist bindir + "\Release_x86\Notepad2.exe"
  #error Compile Notepad2 x86 first
#endif

#ifnexist bindir + "\Release_x64\Notepad2.exe"
  #error Compile Notepad2 x64 first
#endif

#define VerMajor
#define VerMinor
#define VerBuild
#define VerRevision

#expr ParseVersion(bindir + "\Release_x86\Notepad2.exe", VerMajor, VerMinor, VerBuild, VerRevision)
#define app_version   str(VerMajor) + "." + str(VerMinor) + "." + str(VerBuild) + "." + str(VerRevision)
#define app_name      "Notepad2-mod"
#define app_copyright "Copyright  2004-2011, Florian Balmer et al."
#define quick_launch  "{userappdata}\Microsoft\Internet Explorer\Quick Launch"

[Setup]
AppId={#app_name}
AppName={#app_name}
AppVersion={#app_version}
AppVerName={#app_name} {#app_version}
AppPublisher=XhmikosR
AppPublisherURL=http://code.google.com/p/notepad2-mod/
AppSupportURL=http://code.google.com/p/notepad2-mod/
AppUpdatesURL=http://code.google.com/p/notepad2-mod/
AppContact=http://code.google.com/p/notepad2-mod/
AppCopyright={#app_copyright}
VersionInfoCompany=XhmikosR
VersionInfoCopyright={#app_copyright}
VersionInfoDescription={#app_name} {#app_version} Setup
VersionInfoTextVersion={#app_version}
VersionInfoVersion={#app_version}
VersionInfoProductName={#app_name}
VersionInfoProductVersion={#app_version}
VersionInfoProductTextVersion={#app_version}
UninstallDisplayIcon={app}\Notepad2.exe
UninstallDisplayName={#app_name} {#app_version} ({#compiler})
DefaultDirName={pf}\Notepad2
LicenseFile=license.txt
OutputDir=.
OutputBaseFilename={#app_name}.{#app_version}_{#compiler}
SetupIconFile=Setup.ico
WizardImageFile=compiler:WizModernImage-IS.bmp
WizardSmallImageFile=WizardSmallImageFile.bmp
Compression=lzma2/max
InternalCompressLevel=max
SolidCompression=yes
EnableDirDoesntExistWarning=no
AllowNoIcons=yes
ShowTasksTreeLines=yes
DisableDirPage=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes
DisableWelcomePage=yes
AllowCancelDuringInstall=no
#if defined(WDK)
MinVersion=0,5.0
#else
MinVersion=0,5.1.2600sp3
#endif
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64

[Languages]
Name: en; MessagesFile: compiler:Default.isl

[Messages]
BeveledLabel     ={#app_name} {#app_version}  -  Compiled with {#compiler}
SetupAppTitle    =Setup - {#app_name}
SetupWindowTitle =Setup - {#app_name}

[CustomMessages]
en.msg_AppIsRunning          =Setup has detected that {#app_name} is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
en.msg_AppIsRunningUninstall =Uninstall has detected that {#app_name} is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
en.msg_DeleteSettings        =Do you also want to delete {#app_name}'s settings?%n%nIf you plan on installing {#app_name} again then you do not have to delete them.
en.msg_SetupIsRunningWarning ={#app_name} setup is already running!
#if defined(sse_required)
en.msg_simd_sse              =This build of {#app_name} requires a CPU with SSE extension support.%n%nYour CPU does not have those capabilities.
#elif defined(sse2_required)
en.msg_simd_sse2             =This build of {#app_name} requires a CPU with SSE2 extension support.%n%nYour CPU does not have those capabilities.
#endif
en.tsk_AllUsers              =For all users
en.tsk_CurrentUser           =For the current user only
en.tsk_Other                 =Other tasks:
en.tsk_ResetSettings         =Reset {#app_name}'s settings
en.tsk_RemoveDefault         =Restore Windows notepad
en.tsk_SetDefault            =Replace Windows notepad with {#app_name}

[Tasks]
Name: desktopicon;        Description: {cm:CreateDesktopIcon};     GroupDescription: {cm:AdditionalIcons}; Flags: unchecked
Name: desktopicon\user;   Description: {cm:tsk_CurrentUser};       GroupDescription: {cm:AdditionalIcons}; Flags: unchecked exclusive
Name: desktopicon\common; Description: {cm:tsk_AllUsers};          GroupDescription: {cm:AdditionalIcons}; Flags: unchecked exclusive
Name: quicklaunchicon;    Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked;             OnlyBelowVersion: 0,6.01
Name: reset_settings;     Description: {cm:tsk_ResetSettings};     GroupDescription: {cm:tsk_Other};       Flags: checkedonce unchecked; Check: SettingsExistCheck()
Name: set_default;        Description: {cm:tsk_SetDefault};        GroupDescription: {cm:tsk_Other};                                     Check: not DefaulNotepadCheck()
Name: remove_default;     Description: {cm:tsk_RemoveDefault};     GroupDescription: {cm:tsk_Other};       Flags: checkedonce unchecked; Check: DefaulNotepadCheck()

[Files]
Source: psvince.dll;                        DestDir: {app};                  Flags: ignoreversion
Source: ..\License.txt;                     DestDir: {app};                  Flags: ignoreversion
Source: {#bindir}\Release_x64\Notepad2.exe; DestDir: {app};                  Flags: ignoreversion;                         Check: Is64BitInstallMode()
Source: {#bindir}\Release_x86\Notepad2.exe; DestDir: {app};                  Flags: ignoreversion;                         Check: not Is64BitInstallMode()
Source: Notepad2.ini;                       DestDir: {userappdata}\Notepad2; Flags: onlyifdoesntexist uninsneveruninstall
Source: ..\Notepad2.txt;                    DestDir: {app};                  Flags: ignoreversion
Source: ..\Readme.txt;                      DestDir: {app};                  Flags: ignoreversion
Source: ..\Readme-mod.txt;                  DestDir: {app};                  Flags: ignoreversion

[Icons]
Name: {commondesktop}\{#app_name}; Filename: {app}\Notepad2.exe; Tasks: desktopicon\common; Comment: {#app_name} {#app_version}; WorkingDir: {app}; AppUserModelID: Notepad2; IconFilename: {app}\Notepad2.exe; IconIndex: 0
Name: {userdesktop}\{#app_name};   Filename: {app}\Notepad2.exe; Tasks: desktopicon\user;   Comment: {#app_name} {#app_version}; WorkingDir: {app}; AppUserModelID: Notepad2; IconFilename: {app}\Notepad2.exe; IconIndex: 0
Name: {#quick_launch}\{#app_name}; Filename: {app}\Notepad2.exe; Tasks: quicklaunchicon;    Comment: {#app_name} {#app_version}; WorkingDir: {app};                           IconFilename: {app}\Notepad2.exe; IconIndex: 0

[INI]
Filename: {app}\Notepad2.ini; Section: Notepad2; Key: Notepad2.ini; String: %APPDATA%\Notepad2\Notepad2.ini

[Run]
Filename: {app}\Notepad2.exe; Description: {cm:LaunchProgram,{#app_name}}; WorkingDir: {app}; Flags: nowait postinstall skipifsilent unchecked

[InstallDelete]
Type: files;      Name: {userdesktop}\{#app_name}.lnk;   Check: not IsTaskSelected('desktopicon\user')   and IsUpgrade()
Type: files;      Name: {commondesktop}\{#app_name}.lnk; Check: not IsTaskSelected('desktopicon\common') and IsUpgrade()
Type: files;      Name: {#quick_launch}\{#app_name}.lnk; Check: not IsTaskSelected('quicklaunchicon')    and IsUpgrade(); OnlyBelowVersion: 0,6.01
Type: files;      Name: {app}\Notepad2.ini;              Check: IsUpgrade()

[UninstallDelete]
Type: files;      Name: {app}\Notepad2.ini
Type: dirifempty; Name: {app}

[Code]
const
  installer_mutex = '{#app_name}' + '_setup_mutex';
  IFEO            = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe';

function IsModuleLoaded(modulename: AnsiString): Boolean;
external 'IsModuleLoaded2@files:psvince.dll stdcall setuponly';

function IsModuleLoadedU(modulename: AnsiString): Boolean;
external 'IsModuleLoaded2@{app}\psvince.dll stdcall uninstallonly';

#if defined(sse_required) || defined(sse2_required)
function IsProcessorFeaturePresent(Feature: Integer): Boolean;
external 'IsProcessorFeaturePresent@kernel32.dll stdcall';
#endif

// Check if Notepad2 has replaced Windows Notepad
function DefaulNotepadCheck(): Boolean;
var
  sDebugger: String;
begin
  if RegQueryStringValue(HKLM, IFEO, 'Debugger', sDebugger) and
  (sDebugger = (ExpandConstant('"{app}\Notepad2.exe" /z'))) then begin
    Log('Custom Code: {#app_name} is set as the default notepad');
    Result := True;
  end
  else begin
    Log('Custom Code: {#app_name} is NOT set as the default notepad');
    Result := False;
  end;
end;

#if defined(sse_required)
function Is_SSE_Supported(): Boolean;
begin
  // PF_XMMI_INSTRUCTIONS_AVAILABLE
  Result := IsProcessorFeaturePresent(6);
end;

#elif defined(sse2_required)

function Is_SSE2_Supported(): Boolean;
begin
  // PF_XMMI64_INSTRUCTIONS_AVAILABLE
  Result := IsProcessorFeaturePresent(10);
end;

#endif

function IsOldBuildInstalled(sInfFile: String): Boolean;
begin
  if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad2') and
  FileExists(ExpandConstant('{pf}\Notepad2\' + sInfFile)) then
    Result := True
  else
    Result := False;
end;

function IsUpgrade(): Boolean;
var
  sPrevPath: String;
begin
  sPrevPath := WizardForm.PrevAppDir;
  Result := (sPrevPath <> '');
end;

// Check if Notepad2's settings exist
function SettingsExistCheck(): Boolean;
begin
  if FileExists(ExpandConstant('{userappdata}\Notepad2\Notepad2.ini')) then begin
    Log('Custom Code: Settings are present');
    Result := True;
  end
  else begin
    Log('Custom Code: Settings are NOT present');
    Result := False;
  end;
end;

function UninstallOldVersion(sInfFile: String): Integer;
var
  iResultCode: Integer;
begin
  // Return Values:
  // 0 - no idea
  // 1 - error executing the command
  // 2 - successfully executed the command

  // default return value
  Result := 0;
  // TODO: use RegQueryStringValue
  if not Exec('rundll32.exe', ExpandConstant('advpack.dll,LaunchINFSectionEx ' + '"{pf}\Notepad2\' + sInfFile +'",DefaultUninstall,,8,N'), '', SW_HIDE, ewWaitUntilTerminated, iResultCode) then begin
    Result := 1;
  end
  else begin
    Result := 2;
    Sleep(200);
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  // Hide the license page
  if IsUpgrade() and (PageID = wpLicense) then
    Result := True
  else
    Result := False;
end;

procedure AddReg();
begin
  RegWriteStringValue(HKCR, 'Applications\notepad2.exe', 'AppUserModelID', 'Notepad2');
  RegWriteStringValue(HKCR, 'Applications\notepad2.exe\shell\open\command', '', ExpandConstant('"{app}\Notepad2.exe" %1'));
  RegWriteStringValue(HKCR, '*\OpenWithList\notepad2.exe', '', '');
end;

procedure RemoveReg();
begin
  RegDeleteKeyIncludingSubkeys(HKCR, 'Applications\notepad2.exe');
  RegDeleteKeyIncludingSubkeys(HKCR, '*\OpenWithList\notepad2.exe');
end;

procedure CleanUpSettings();
begin
  DeleteFile(ExpandConstant('{userappdata}\Notepad2\Notepad2.ini'));
  RemoveDir(ExpandConstant('{userappdata}\Notepad2'));
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  if CurPageID = wpSelectTasks then
    WizardForm.NextButton.Caption := SetupMessage(msgButtonInstall)
  else if CurPageID = wpFinished then
    WizardForm.NextButton.Caption := SetupMessage(msgButtonFinish);
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin

  if CurStep = ssInstall then begin
    if IsOldBuildInstalled('Uninstall.inf') or IsOldBuildInstalled('Notepad2.inf') then begin

      if IsOldBuildInstalled('Uninstall.inf') then begin
        Log('Custom Code: The old build is installed, will try to uninstall it');
        if UninstallOldVersion('Uninstall.inf') = 2 then
          Log('Custom Code: The old build was successfully uninstalled')
        else
          Log('Custom Code: Something went wrong when uninstalling the old build');
      end;

      if IsOldBuildInstalled('Notepad2.inf') then begin
        Log('Custom Code: The official Notepad2 build is installed, will try to uninstall it');
        if UninstallOldVersion('Notepad2.inf') = 2 then
          Log('Custom Code: The official Notepad2 build was successfully uninstalled')
        else
          Log('Custom Code: Something went wrong when uninstalling the official Notepad2 build');
      end;

      // This is the case where the old build is installed; the DefaulNotepadCheck() returns true
      // and the set_default task isn't selected
      if not IsTaskSelected('remove_default') then
        RegWriteStringValue(HKLM, IFEO, 'Debugger', ExpandConstant('"{app}\Notepad2.exe" /z'));

    end
    else
      Log('Custom Code: No other known build is currently installed');
  end;

  if CurStep = ssPostInstall then begin
    if IsTaskSelected('reset_settings') then
      CleanUpSettings();

    if IsTaskSelected('set_default') then
      RegWriteStringValue(HKLM, IFEO, 'Debugger', ExpandConstant('"{app}\Notepad2.exe" /z'));

    if IsTaskSelected('remove_default') then begin
      RegDeleteValue(HKLM, IFEO, 'Debugger');
      RegDeleteKeyIfEmpty(HKLM, IFEO);
    end;

    // Always add Notepad2's AppUserModelID and the rest registry values
    AddReg();
  end;

end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  // When uninstalling, ask the user to delete Notepad2's settings
  if CurUninstallStep = usUninstall then begin
    if SettingsExistCheck() then begin
      if SuppressibleMsgBox(CustomMessage('msg_DeleteSettings'), mbConfirmation, MB_YESNO or MB_DEFBUTTON2, IDNO) = IDYES then begin
        CleanUpSettings();
      end;
    end;

    if DefaulNotepadCheck() then
      RegDeleteValue(HKLM, IFEO, 'Debugger');
    RegDeleteKeyIfEmpty(HKLM, IFEO);
    RemoveReg();

  end;
end;

procedure InitializeWizard();
begin
  WizardForm.SelectTasksLabel.Hide;
  WizardForm.TasksList.Top    := 0;
  WizardForm.TasksList.Height := PageFromID(wpSelectTasks).SurfaceHeight;
end;

function InitializeSetup(): Boolean;
var
  iMsgBoxResult: Integer;
begin
  // Create a mutex for the installer and if it's already running then show a message and stop installation
  if CheckForMutexes(installer_mutex) and not WizardSilent() then begin
    SuppressibleMsgBox(CustomMessage('msg_SetupIsRunningWarning'), mbError, MB_OK, MB_OK);
    Result := False;
  end
  else begin
    Result := True;
    CreateMutex(installer_mutex);

    while IsModuleLoaded('Notepad2.exe') and (iMsgBoxResult <> IDCANCEL) do
      iMsgBoxResult := SuppressibleMsgBox(CustomMessage('msg_AppIsRunning'), mbError, MB_OKCANCEL, IDCANCEL);

    if iMsgBoxResult = IDCANCEL then
      Result := False;

#if defined(sse2_required)
    if not Is_SSE2_Supported() then begin
      SuppressibleMsgBox(CustomMessage('msg_simd_sse2'), mbCriticalError, MB_OK, MB_OK);
      Result := False;
    end;
#elif defined(sse_required)
    if not Is_SSE_Supported() then begin
      SuppressibleMsgBox(CustomMessage('msg_simd_sse'), mbCriticalError, MB_OK, MB_OK);
      Result := False;
    end;
#endif

  end;
end;

function InitializeUninstall(): Boolean;
var
  iMsgBoxResult: Integer;
begin
  if CheckForMutexes(installer_mutex) then begin
    SuppressibleMsgBox(CustomMessage('msg_SetupIsRunningWarning'), mbError, MB_OK, MB_OK);
    Result := False;
  end
  else begin
    Result := True;
    CreateMutex(installer_mutex);

    // Check if app is running during uninstallation
    while IsModuleLoadedU('Notepad2.exe') and (iMsgBoxResult <> IDCANCEL) do
      iMsgBoxResult := SuppressibleMsgBox(CustomMessage('msg_AppIsRunningUninstall'), mbError, MB_OKCANCEL, IDCANCEL);

    if iMsgBoxResult = IDCANCEL then
      Result := False;

    // Unload psvince.dll in order to be uninstalled
    UnloadDLL(ExpandConstant('{app}\psvince.dll'));
  end;
end;

;* Notepad2-mod - Installer script
;*
;* Copyright (C) 2010-2011 XhmikosR
;*
;* This file is part of Notepad2-mod.
;*
;* See License.txt for details.

; Requirements:
; Inno Setup v5.4.2(+): http://www.jrsoftware.org/isdl.php

; $Id$

;#define ICL12
;#define VS2010
;#define WDK

; Preprocessor related stuff
#if VER < 0x05040200
  #error Update your Inno Setup version
#endif

#if !defined(ICL12) && !defined(VS2010) && !defined(WDK)
  #error You need to define ICL12 or VS2010 or WDK first
#endif

#if defined(ICL12) && (defined(VS2010) || defined(WDK))
  #error You can't define ICL12 and at the same time
#endif

#if defined(VS2010) && ( defined(ICL12) || defined(WDK))
  #error You can't define WDK and at the same time
#endif

#if defined(WDK) && (defined(ICL12) || defined(VS2010))
  #error You can't use two defines at the same time
#endif

#if defined(ICL12)
  #define compiler "ICL12"
  #define sse2_required
#elif defined(VS2010)
  #define compiler "VS2010"
#elif defined(WDK)
  #define compiler "WDK"
#endif

#define bindir       "..\bin\" + compiler

#ifnexist SourcePath + bindir + "\Release_x86\Notepad2.exe"
  #error Compile Notepad2 x86 first
#endif

#ifnexist SourcePath + bindir + "\Release_x64\Notepad2.exe"
  #error Compile Notepad2 x64 first
#endif

#define VerMajor
#define VerMinor
#define VerBuild
#define VerRevision

#expr ParseVersion(bindir + "\Release_x86\Notepad2.exe", VerMajor, VerMinor, VerBuild, VerRevision)
#define app_version   str(VerMajor) + "." + str(VerMinor) + "." + str(VerBuild) + "." + str(VerRevision)
#define app_name      "Notepad2-mod"
#define app_copyright "Copyright  2004-2011, Florian Balmer et al."
#define quick_launch  "{userappdata}\Microsoft\Internet Explorer\Quick Launch"

[Setup]
AppId={#app_name}
AppName={#app_name}
AppVersion={#app_version}
AppVerName={#app_name} {#app_version}
AppPublisher=XhmikosR
AppPublisherURL=http://code.google.com/p/notepad2-mod/
AppSupportURL=http://code.google.com/p/notepad2-mod/
AppUpdatesURL=http://code.google.com/p/notepad2-mod/
AppContact=http://code.google.com/p/notepad2-mod/
AppCopyright={#app_copyright}
VersionInfoCompany=XhmikosR
VersionInfoCopyright={#app_copyright}
VersionInfoDescription={#app_name} {#app_version} Setup
VersionInfoTextVersion={#app_version}
VersionInfoVersion={#app_version}
VersionInfoProductName={#app_name}
VersionInfoProductVersion={#app_version}
VersionInfoProductTextVersion={#app_version}
UninstallDisplayIcon={app}\Notepad2.exe
UninstallDisplayName={#app_name} {#app_version} ({#compiler})
DefaultDirName={pf}\Notepad2
LicenseFile=license.txt
OutputDir=.
OutputBaseFilename={#app_name}.{#app_version}_{#compiler}
SetupIconFile=Setup.ico
WizardImageFile=compiler:WizModernImage-IS.bmp
WizardSmallImageFile=WizardSmallImageFile.bmp
Compression=lzma2/max
InternalCompressLevel=max
SolidCompression=yes
EnableDirDoesntExistWarning=no
AllowNoIcons=yes
ShowTasksTreeLines=yes
DisableDirPage=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes
DisableWelcomePage=yes
AllowCancelDuringInstall=no
#if defined(WDK)
MinVersion=0,5.0
#else
MinVersion=0,5.1.2600sp3
#endif
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64

[Languages]
Name: en; MessagesFile: compiler:Default.isl

[Messages]
BeveledLabel     ={#app_name} {#app_version}  -  Compiled with {#compiler}
SetupAppTitle    =Setup - {#app_name}
SetupWindowTitle =Setup - {#app_name}

[CustomMessages]
en.msg_AppIsRunning          =Setup has detected that {#app_name} is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
en.msg_AppIsRunningUninstall =Uninstall has detected that {#app_name} is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
en.msg_DeleteSettings        =Do you also want to delete {#app_name}'s settings?%n%nIf you plan on installing {#app_name} again then you do not have to delete them.
en.msg_SetupIsRunningWarning ={#app_name} setup is already running!
#if defined(sse_required)
en.msg_simd_sse              =This build of {#app_name} requires a CPU with SSE extension support.%n%nYour CPU does not have those capabilities.
#elif defined(sse2_required)
en.msg_simd_sse2             =This build of {#app_name} requires a CPU with SSE2 extension support.%n%nYour CPU does not have those capabilities.
#endif
en.tsk_AllUsers              =For all users
en.tsk_CurrentUser           =For the current user only
en.tsk_Other                 =Other tasks:
en.tsk_ResetSettings         =Reset {#app_name}'s settings
en.tsk_RemoveDefault         =Restore Windows notepad
en.tsk_SetDefault            =Replace Windows notepad with {#app_name}

[Tasks]
Name: desktopicon;        Description: {cm:CreateDesktopIcon};     GroupDescription: {cm:AdditionalIcons}; Flags: unchecked
Name: desktopicon\user;   Description: {cm:tsk_CurrentUser};       GroupDescription: {cm:AdditionalIcons}; Flags: unchecked exclusive
Name: desktopicon\common; Description: {cm:tsk_AllUsers};          GroupDescription: {cm:AdditionalIcons}; Flags: unchecked exclusive
Name: quicklaunchicon;    Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked;             OnlyBelowVersion: 0,6.01
Name: reset_settings;     Description: {cm:tsk_ResetSettings};     GroupDescription: {cm:tsk_Other};       Flags: checkedonce unchecked; Check: SettingsExistCheck()
Name: set_default;        Description: {cm:tsk_SetDefault};        GroupDescription: {cm:tsk_Other};                                     Check: not DefaulNotepadCheck()
Name: remove_default;     Description: {cm:tsk_RemoveDefault};     GroupDescription: {cm:tsk_Other};       Flags: checkedonce unchecked; Check: DefaulNotepadCheck()

[Files]
Source: psvince.dll;                        DestDir: {app};                  Flags: ignoreversion
Source: ..\License.txt;                     DestDir: {app};                  Flags: ignoreversion
Source: {#bindir}\Release_x64\Notepad2.exe; DestDir: {app};                  Flags: ignoreversion;                         Check: Is64BitInstallMode()
Source: {#bindir}\Release_x86\Notepad2.exe; DestDir: {app};                  Flags: ignoreversion;                         Check: not Is64BitInstallMode()
Source: Notepad2.ini;                       DestDir: {userappdata}\Notepad2; Flags: onlyifdoesntexist uninsneveruninstall
Source: ..\Notepad2.txt;                    DestDir: {app};                  Flags: ignoreversion
Source: ..\Readme.txt;                      DestDir: {app};                  Flags: ignoreversion
Source: ..\Readme-mod.txt;                  DestDir: {app};                  Flags: ignoreversion

[Icons]
Name: {commondesktop}\{#app_name}; Filename: {app}\Notepad2.exe; Tasks: desktopicon\common; Comment: {#app_name} {#app_version}; WorkingDir: {app}; AppUserModelID: Notepad2; IconFilename: {app}\Notepad2.exe; IconIndex: 0
Name: {userdesktop}\{#app_name};   Filename: {app}\Notepad2.exe; Tasks: desktopicon\user;   Comment: {#app_name} {#app_version}; WorkingDir: {app}; AppUserModelID: Notepad2; IconFilename: {app}\Notepad2.exe; IconIndex: 0
Name: {#quick_launch}\{#app_name}; Filename: {app}\Notepad2.exe; Tasks: quicklaunchicon;    Comment: {#app_name} {#app_version}; WorkingDir: {app};                           IconFilename: {app}\Notepad2.exe; IconIndex: 0

[INI]
Filename: {app}\Notepad2.ini; Section: Notepad2; Key: Notepad2.ini; String: %APPDATA%\Notepad2\Notepad2.ini

[Run]
Filename: {app}\Notepad2.exe; Description: {cm:LaunchProgram,{#app_name}}; WorkingDir: {app}; Flags: nowait postinstall skipifsilent unchecked

[InstallDelete]
Type: files;      Name: {userdesktop}\{#app_name}.lnk;   Check: not IsTaskSelected('desktopicon\user')   and IsUpgrade()
Type: files;      Name: {commondesktop}\{#app_name}.lnk; Check: not IsTaskSelected('desktopicon\common') and IsUpgrade()
Type: files;      Name: {#quick_launch}\{#app_name}.lnk; Check: not IsTaskSelected('quicklaunchicon')    and IsUpgrade(); OnlyBelowVersion: 0,6.01
Type: files;      Name: {app}\Notepad2.ini;              Check: IsUpgrade()

[UninstallDelete]
Type: files;      Name: {app}\Notepad2.ini
Type: dirifempty; Name: {app}

[Code]
const
  installer_mutex = '{#app_name}' + '_setup_mutex';
  IFEO            = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe';

function IsModuleLoaded(modulename: AnsiString): Boolean;
external 'IsModuleLoaded2@files:psvince.dll stdcall setuponly';

function IsModuleLoadedU(modulename: AnsiString): Boolean;
external 'IsModuleLoaded2@{app}\psvince.dll stdcall uninstallonly';

#if defined(sse_required) || defined(sse2_required)
function IsProcessorFeaturePresent(Feature: Integer): Boolean;
external 'IsProcessorFeaturePresent@kernel32.dll stdcall';
#endif

// Check if Notepad2 has replaced Windows Notepad
function DefaulNotepadCheck(): Boolean;
var
  sDebugger: String;
begin
  if RegQueryStringValue(HKLM, IFEO, 'Debugger', sDebugger) and
  (sDebugger = (ExpandConstant('"{app}\Notepad2.exe" /z'))) then begin
    Log('Custom Code: {#app_name} is set as the default notepad');
    Result := True;
  end
  else begin
    Log('Custom Code: {#app_name} is NOT set as the default notepad');
    Result := False;
  end;
end;

#if defined(sse_required)
function Is_SSE_Supported(): Boolean;
begin
  // PF_XMMI_INSTRUCTIONS_AVAILABLE
  Result := IsProcessorFeaturePresent(6);
end;

#elif defined(sse2_required)

function Is_SSE2_Supported(): Boolean;
begin
  // PF_XMMI64_INSTRUCTIONS_AVAILABLE
  Result := IsProcessorFeaturePresent(10);
end;

#endif

function IsOldBuildInstalled(sInfFile: String): Boolean;
begin
  if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad2') and
  FileExists(ExpandConstant('{pf}\Notepad2\' + sInfFile)) then
    Result := True
  else
    Result := False;
end;

function IsUpgrade(): Boolean;
var
  sPrevPath: String;
begin
  sPrevPath := WizardForm.PrevAppDir;
  Result := (sPrevPath <> '');
end;

// Check if Notepad2's settings exist
function SettingsExistCheck(): Boolean;
begin
  if FileExists(ExpandConstant('{userappdata}\Notepad2\Notepad2.ini')) then begin
    Log('Custom Code: Settings are present');
    Result := True;
  end
  else begin
    Log('Custom Code: Settings are NOT present');
    Result := False;
  end;
end;

function UninstallOldVersion(sInfFile: String): Integer;
var
  iResultCode: Integer;
begin
  // Return Values:
  // 0 - no idea
  // 1 - error executing the command
  // 2 - successfully executed the command

  // default return value
  Result := 0;
  // TODO: use RegQueryStringValue
  if not Exec('rundll32.exe', ExpandConstant('advpack.dll,LaunchINFSectionEx ' + '"{pf}\Notepad2\' + sInfFile +'",DefaultUninstall,,8,N'), '', SW_HIDE, ewWaitUntilTerminated, iResultCode) then begin
    Result := 1;
  end
  else begin
    Result := 2;
    Sleep(200);
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  // Hide the license page
  if IsUpgrade() and (PageID = wpLicense) then
    Result := True
  else
    Result := False;
end;

procedure AddReg();
begin
  RegWriteStringValue(HKCR, 'Applications\notepad2.exe', 'AppUserModelID', 'Notepad2');
  RegWriteStringValue(HKCR, 'Applications\notepad2.exe\shell\open\command', '', ExpandConstant('"{app}\Notepad2.exe" %1'));
  RegWriteStringValue(HKCR, '*\OpenWithList\notepad2.exe', '', '');
end;

procedure RemoveReg();
begin
  RegDeleteKeyIncludingSubkeys(HKCR, 'Applications\notepad2.exe');
  RegDeleteKeyIncludingSubkeys(HKCR, '*\OpenWithList\notepad2.exe');
end;

procedure CleanUpSettings();
begin
  DeleteFile(ExpandConstant('{userappdata}\Notepad2\Notepad2.ini'));
  RemoveDir(ExpandConstant('{userappdata}\Notepad2'));
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  if CurPageID = wpSelectTasks then
    WizardForm.NextButton.Caption := SetupMessage(msgButtonInstall)
  else if CurPageID = wpFinished then
    WizardForm.NextButton.Caption := SetupMessage(msgButtonFinish);
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin

  if CurStep = ssInstall then begin
    if IsOldBuildInstalled('Uninstall.inf') or IsOldBuildInstalled('Notepad2.inf') then begin

      if IsOldBuildInstalled('Uninstall.inf') then begin
        Log('Custom Code: The old build is installed, will try to uninstall it');
        if UninstallOldVersion('Uninstall.inf') = 2 then
          Log('Custom Code: The old build was successfully uninstalled')
        else
          Log('Custom Code: Something went wrong when uninstalling the old build');
      end;

      if IsOldBuildInstalled('Notepad2.inf') then begin
        Log('Custom Code: The official Notepad2 build is installed, will try to uninstall it');
        if UninstallOldVersion('Notepad2.inf') = 2 then
          Log('Custom Code: The official Notepad2 build was successfully uninstalled')
        else
          Log('Custom Code: Something went wrong when uninstalling the official Notepad2 build');
      end;

      // This is the case where the old build is installed; the DefaulNotepadCheck() returns true
      // and the set_default task isn't selected
      if not IsTaskSelected('remove_default') then
        RegWriteStringValue(HKLM, IFEO, 'Debugger', ExpandConstant('"{app}\Notepad2.exe" /z'));

    end
    else
      Log('Custom Code: No other known build is currently installed');
  end;

  if CurStep = ssPostInstall then begin
    if IsTaskSelected('reset_settings') then
      CleanUpSettings();

    if IsTaskSelected('set_default') then
      RegWriteStringValue(HKLM, IFEO, 'Debugger', ExpandConstant('"{app}\Notepad2.exe" /z'));

    if IsTaskSelected('remove_default') then begin
      RegDeleteValue(HKLM, IFEO, 'Debugger');
      RegDeleteKeyIfEmpty(HKLM, IFEO);
    end;

    // Always add Notepad2's AppUserModelID and the rest registry values
    AddReg();
  end;

end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  // When uninstalling, ask the user to delete Notepad2's settings
  if CurUninstallStep = usUninstall then begin
    if SettingsExistCheck() then begin
      if SuppressibleMsgBox(CustomMessage('msg_DeleteSettings'), mbConfirmation, MB_YESNO or MB_DEFBUTTON2, IDNO) = IDYES then begin
        CleanUpSettings();
      end;
    end;

    if DefaulNotepadCheck() then
      RegDeleteValue(HKLM, IFEO, 'Debugger');
    RegDeleteKeyIfEmpty(HKLM, IFEO);
    RemoveReg();

  end;
end;

procedure InitializeWizard();
begin
  WizardForm.SelectTasksLabel.Hide;
  WizardForm.TasksList.Top    := 0;
  WizardForm.TasksList.Height := PageFromID(wpSelectTasks).SurfaceHeight;
end;

function InitializeSetup(): Boolean;
var
  iMsgBoxResult: Integer;
begin
  // Create a mutex for the installer and if it's already running then show a message and stop installation
  if CheckForMutexes(installer_mutex) and not WizardSilent() then begin
    SuppressibleMsgBox(CustomMessage('msg_SetupIsRunningWarning'), mbError, MB_OK, MB_OK);
    Result := False;
  end
  else begin
    Result := True;
    CreateMutex(installer_mutex);

    while IsModuleLoaded('Notepad2.exe') and (iMsgBoxResult <> IDCANCEL) do
      iMsgBoxResult := SuppressibleMsgBox(CustomMessage('msg_AppIsRunning'), mbError, MB_OKCANCEL, IDCANCEL);

    if iMsgBoxResult = IDCANCEL then
      Result := False;

#if defined(sse2_required)
    if not Is_SSE2_Supported() then begin
      SuppressibleMsgBox(CustomMessage('msg_simd_sse2'), mbCriticalError, MB_OK, MB_OK);
      Result := False;
    end;
#elif defined(sse_required)
    if not Is_SSE_Supported() then begin
      SuppressibleMsgBox(CustomMessage('msg_simd_sse'), mbCriticalError, MB_OK, MB_OK);
      Result := False;
    end;
#endif

  end;
end;

function InitializeUninstall(): Boolean;
var
  iMsgBoxResult: Integer;
begin
  if CheckForMutexes(installer_mutex) then begin
    SuppressibleMsgBox(CustomMessage('msg_SetupIsRunningWarning'), mbError, MB_OK, MB_OK);
    Result := False;
  end
  else begin
    Result := True;
    CreateMutex(installer_mutex);

    // Check if app is running during uninstallation
    while IsModuleLoadedU('Notepad2.exe') and (iMsgBoxResult <> IDCANCEL) do
      iMsgBoxResult := SuppressibleMsgBox(CustomMessage('msg_AppIsRunningUninstall'), mbError, MB_OKCANCEL, IDCANCEL);

    if iMsgBoxResult = IDCANCEL then
      Result := False;

    // Unload psvince.dll in order to be uninstalled
    UnloadDLL(ExpandConstant('{app}\psvince.dll'));
  end;
end;