Update the `logtalk.iss` script to also remove hyphens from the version string when shortening it

; This file is part of Logtalk <http://logtalk.org/>
; Copyright (c) 1998-2013 Paulo Moura <pmoura@logtalk.org>
;
; Logtalk is free software. You can redistribute it and/or modify it under
; the terms of the FSF GNU General Public License 3  (plus some additional
; terms per section 7).        Consult the `LICENSE.txt` file for details.

#define MyAppName "Logtalk"
#define MyAppPublisher "Logtalk.org"
#define MyAppURL "http://logtalk.org"
#define MyAppUrlName "Logtalk Web Site.url"
#define MyAppRegURL "http://logtalk.org/regform.html"
#define MyAppRegUrlName "Logtalk Registration.url"

#define MyBaseDir "C:\lgt3git"
#define MyAppVer FileRead(FileOpen(MyBaseDir + "\VERSION.txt"))
#define MyAppVerNumberString StringChange(StringChange(MyAppVer, ".", ""), "-", "")
#define MyAppVerNumberInteger Int(MyAppVerNumberString)

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppName} {#MyAppVer}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ChangesEnvironment=yes
ChangesAssociations=yes
DefaultDirName={pf}\Logtalk
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
LicenseFile={#MyBaseDir}\scripts\windows\LICENSE.rtf
InfoBeforeFile={#MyBaseDir}\scripts\windows\README.rtf
; SetupIconFile={#MyBaseDir}\scripts\windows\logtalk.ico
OutputBaseFilename=lgt{#MyAppVerNumberString}
Compression=lzma
SolidCompression=yes
PrivilegesRequired=none

VersionInfoVersion={#MyAppVer}
VersionInfoCopyright= Paulo Moura, Copyright (c) 1998-2013

AllowRootDirectory=yes
UninstallFilesDir="{userdocs}\Logtalk uninstaller"

MinVersion=0,5.0

[Types]
Name: "full"; Description: "Full installation"
Name: "base"; Description: "Base system installation"
Name: "user"; Description: "User files installation"
Name: "prolog"; Description: "Prolog integration shortcuts"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "base"; Description: "Base system (compiler/runtime, Prolog integration files, manuals)"; Types: full base custom; Flags: disablenouninstallwarning
Name: "user"; Description: "User files (libraries, examples, and other support files)"; Types: full user custom; Flags: checkablealone disablenouninstallwarning
Name: "user\backup"; Description: "Backup current Logtalk user folder"; Types: full user custom; Flags: disablenouninstallwarning
Name: "prolog"; Description: "Prolog integration (back-end compiler support)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\bp"; Description: "B-Prolog integration (version 7.8 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\cxprolog"; Description: "CxProlog integration (version 0.97.6 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\eclipse"; Description: "ECLiPSe integration (version 6.0#141 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\gprolog"; Description: "GNU Prolog integration (version 1.4.1 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\lean"; Description: "Lean Prolog Prolog integration (version 3.7.10 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\sicstus"; Description: "SICStus Prolog integration (version 4.1.0 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\swicon"; Description: "SWI-Prolog (console) integration (version 6.0.0 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\swiwin"; Description: "SWI-Prolog (window) integration (version 6.0.0 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\xsb"; Description: "XSB integration (version 3.3 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\xsbmt"; Description: "XSB-MT integration (version 3.3 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\yap"; Description: "YAP (console) integration (version 6.0.2 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\yap"; Description: "YAP (window) integration (version 6.3.2 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning

[Tasks]
Name: registration; Description: "&Register {#MyAppName} (opens a web page; requires an Internet connection)"; Components: base
Name: shortcut; Description: "&Create a desktop shortcut to the Logtalk user folder"; Components: user

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

[Messages]
BeveledLabel=Logtalk 3.00.0  Paulo Moura, Copyright (c) 1998-2013

[Dirs]
Name: {code:GetLgtUserDir}; Components: user; Flags: uninsneveruninstall
Name: "{userdocs}\Logtalk uninstaller"

[Files]
Source: "{#MyBaseDir}\*"; Excludes: "*.md,.*"; DestDir: "{app}"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyBaseDir}\ACKNOWLEDGMENTS.md"; DestDir: "{app}"; DestName: "ACKNOWLEDGMENTS.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\CUSTOMIZE.md"; DestDir: "{app}"; DestName: "CUSTOMIZE.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\INSTALL.md"; DestDir: "{app}"; DestName: "INSTALL.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\QUICK_START.md"; DestDir: "{app}"; DestName: "QUICK_START.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\README.md"; DestDir: "{app}"; DestName: "README.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\RELEASE_NOTES.md"; DestDir: "{app}"; DestName: "RELEASE_NOTES.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\UPGRADING.md"; DestDir: "{app}"; DestName: "UPGRADING.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist

Source: "{#MyBaseDir}\contributions\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\contributions"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\examples\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\examples"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\library\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\library"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\scratch\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\scratch"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\tools\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\tools"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall

Source: "{#MyBaseDir}\settings-sample.lgt"; DestDir: "{code:GetLgtUserDir}"; DestName: "settings-sample.lgt"; Components: user; Flags: ignoreversion uninsneveruninstall
Source: "{#MyBaseDir}\VERSION.txt"; DestDir: "{code:GetLgtUserDir}"; DestName: "VERSION.txt"; Components: user; Flags: ignoreversion uninsneveruninstall

Source: "{#MyBaseDir}\scripts\*.bat"; DestDir: "{win}"; Components: base; Flags: ignoreversion; Check: IsAdminLoggedOn
Source: "{#MyBaseDir}\tools\lgtdoc\xml\*.bat"; DestDir: "{win}"; Components: base; Flags: ignoreversion; Check: IsAdminLoggedOn

[INI]
Filename: "{app}\{#MyAppUrlName}"; Section: "InternetShortcut"; Key: "URL"; String: "{#MyAppURL}"; Components: base
Filename: "{app}\{#MyAppRegUrlName}"; Section: "InternetShortcut"; Key: "URL"; String: "{#MyAppRegURL}"; Components: base

[Icons]
Name: "{group}\Bibliography"; Filename: "{app}\BIBLIOGRAPHY.bib"; Components: base
Name: "{group}\Documentation"; Filename: "{app}\manuals\index.html"; Components: base
Name: "{group}\License"; Filename: "{app}\LICENSE.txt"; Components: base
Name: "{group}\Release Notes"; Filename: "{app}\RELEASE_NOTES.txt"; Components: base
Name: "{group}\Read Me"; Filename: "{app}\README.txt"; Components: base
Name: "{group}\Customization instructions"; Filename: "{app}\CUSTOMIZE.txt"; Components: base
Name: "{group}\Default settings"; Filename: "%LOGTALKUSER%\settings-sample.lgt"; Components: base

Name: "{group}\Web Site"; Filename: "{#MyAppUrl}"; Components: base

Name: "{group}\Logtalk - B-Prolog"; Filename: "{code:GetBPExePath}"; Parameters: "-i ""$LOGTALKHOME/integration/logtalk_bp.pl"""; Comment: "Runs Logtalk with B-Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\bp; Flags: createonlyiffileexists

Name: "{group}\Logtalk - CxProlog"; Filename: "{code:GetCxExePath}"; Parameters: "--script ""%LOGTALKHOME%\\integration\\logtalk_cx.pl"""; Comment: "Runs Logtalk with CxProlog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\cxprolog; Flags: createonlyiffileexists

Name: "{group}\Logtalk - ECLiPSe 6"; Filename: "{code:GetEclipse6ExePath}"; Parameters: "-b ""$LOGTALKHOME/integration/logtalk_eclipse.pl"""; Comment: "Runs Logtalk with ECLiPSe 6"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\eclipse; Flags: createonlyiffileexists

Name: "{group}\Logtalk - GNU Prolog"; Filename: "{code:GetGPExePath}"; Parameters: "--init-goal ""['$LOGTALKHOME/integration/logtalk_gp.pl']"""; Comment: "Runs Logtalk with GNU Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\gprolog; Flags: createonlyiffileexists

Name: "{group}\Logtalk - Lean Prolog"; Filename: "{code:GetLeanPrologExePath}"; Parameters: """['$LOGTALKHOME/integration/logtalk_lean']"""; Comment: "Runs Logtalk with Lean Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\lean; Flags: createonlyiffileexists

Name: "{group}\Logtalk - SICStus Prolog"; Filename: "{code:GetSICStusExePath}"; Parameters: "-l ""%LOGTALKHOME%\integration\logtalk_sicstus.pl"""; Comment: "Runs Logtalk with SICStus Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\sicstus; Flags: createonlyiffileexists

Name: "{group}\Logtalk - SWI-Prolog (console)"; Filename: "{code:GetSWIConExePath}"; Parameters: "-s ""%LOGTALKHOME%\integration\logtalk_swi.pl"""; Comment: "Runs Logtalk with SWI-Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\swicon; Flags: createonlyiffileexists

Name: "{group}\Logtalk - SWI-Prolog (window)"; Filename: "{code:GetSWIWinExePath}"; Parameters: "-s ""%LOGTALKHOME%\integration\logtalk_swi.pl"""; Comment: "Runs Logtalk with SWI-Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\swiwin; Flags: createonlyiffileexists

Name: "{group}\Logtalk - XSB"; Filename: "{code:GetXSBExePath}"; Parameters: "-l -e ""['%LOGTALKHOME%\\integration\\logtalk_xsb.pl']."""; Comment: "Runs Logtalk with XSB"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\xsb; Flags: createonlyiffileexists

Name: "{group}\Logtalk - XSB-MT"; Filename: "{code:GetXSBMTExePath}"; Parameters: "-l -e ""['%LOGTALKHOME%\\integration\\logtalk_xsbmt.pl']."""; Comment: "Runs Logtalk with XSB-MT"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\xsbmt; Flags: createonlyiffileexists

Name: "{group}\Logtalk - YAP (console)"; Filename: "{code:GetYAPConExePath}"; Parameters: "-l ""$LOGTALKHOME/integration/logtalk_yap.pl"""; Comment: "Runs Logtalk with YAP"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\yap; Flags: createonlyiffileexists

Name: "{group}\Logtalk - YAP (window)"; Filename: "{code:GetYAPWinExePath}"; Parameters: "-l ""$LOGTALKHOME/integration/logtalk_yap.pl"""; Comment: "Runs Logtalk with YAP"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\yap; Flags: createonlyiffileexists

Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; Components: base

Name: "{code:GetLgtUserDir}\Bibliography"; Filename: "{app}\BIBLIOGRAPHY.bib"; Components: user
Name: "{code:GetLgtUserDir}\License"; Filename: "{app}\LICENSE.txt"; Components: user
Name: "{code:GetLgtUserDir}\Release Notes"; Filename: "{app}\RELEASE_NOTES.txt"; Components: user
Name: "{code:GetLgtUserDir}\Read Me"; Filename: "{app}\README.txt"; Components: user
Name: "{code:GetLgtUserDir}\Customization instructions"; Filename: "{app}\CUSTOMIZE.txt"; Components: user
Name: "{code:GetLgtUserDir}\adapters"; Filename: "{app}\adapters"; Components: user
Name: "{code:GetLgtUserDir}\manuals"; Filename: "{app}\manuals"; Components: user
Name: "{code:GetLgtUserDir}\paths"; Filename: "{app}\paths"; Components: user
Name: "{code:GetLgtUserDir}\coding"; Filename: "{app}\coding"; Components: user

Name: "{userdesktop}\Logtalk user files"; Filename: "{code:GetLgtUserDir}"; Components: user; Tasks: shortcut

[Registry]
; admin users
Root: HKLM; Subkey: "Software\Logtalk"; ValueType: dword; ValueName: "Version"; ValueData: "{#MyAppVerNumberInteger}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "LOGTALKHOME"; ValueData: "{app}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKUSER"; ValueData: "{code:GetLgtUserDir}"; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKLM; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; Components: base; Flags: uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKLM; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; ValueType: string; ValueName: "Extension"; ValueData: ".lgt"; Components: base; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKCR; Subkey: ".lgt"; ValueType: string; ValueName: ""; ValueData: "LogtalkSourceFile"; Components: base; Flags: uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKCR; Subkey: "LogtalkSourceFile"; ValueType: string; ValueName: ""; ValueData: "Logtalk source file"; Components: base; Flags: uninsdeletekey; Check: IsAdminLoggedOn
; non-admin users
Root: HKCU; Subkey: "Software\Logtalk"; ValueType: dword; ValueName: "Version"; ValueData: "{#MyAppVerNumberInteger}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKHOME"; ValueData: "{app}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKUSER"; ValueData: "{code:GetLgtUserDir}"; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; Components: base; Flags: uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; ValueType: string; ValueName: "Extension"; ValueData: ".lgt"; Components: base; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\.lgt"; ValueType: string; ValueName: ""; ValueData: "LogtalkSourceFile"; Components: base; Flags: uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\LogtalkSourceFile"; ValueType: string; ValueName: ""; ValueData: "Logtalk source file"; Components: base; Flags: uninsdeletekey; Check: not IsAdminLoggedOn

[Run]
Filename: "{app}\RELEASE_NOTES.txt"; Description: "View the release notes"; Components: base; Flags: postinstall shellexec skipifsilent
Filename: "{app}\CUSTOMIZE.txt"; Description: "Read the customization instructions for completing your setup"; Components: base; Flags: postinstall shellexec skipifsilent

Filename: "{app}\{#MyAppRegUrlName}"; Components: base; Flags: shellexec nowait; Tasks: registration

[UninstallDelete]
Type: filesandordirs; Name: "{app}"; Components: base
Type: filesandordirs; Name: "{group}"; Components: base

[Code]
var
  LgtUserDirPage: TInputDirWizardPage;
  WarningPage, ErrorPage: TOutputMsgWizardPage;
  Explanation, Warning, Error, BackupFolder: String;

function GetLgtUserDir(Param: String): String;
begin
  Result := LgtUserDirPage.Values[0]
end;

function GetCurrentDate(Param: String): String;
begin
  Result := GetDateTimeString('dddddd tt', '-', '-')
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  NewFolder: String;
begin
  NewFolder := LgtUserDirPage.Values[0];
  if (CurStep = ssInstall) and DirExists(NewFolder) and (pos('backup', WizardSelectedComponents(False)) > 0) then begin
    BackupFolder := NewFolder + '-backup-' + GetDateTimeString('yyyy-mm-dd-hhnnss', '-', ':');
    RenameFile(NewFolder, BackupFolder)
  end
  else if (CurStep = ssPostInstall) and FileExists(BackupFolder + '\settings.lgt') then
    FileCopy(BackupFolder + '\settings.lgt', NewFolder + '\settings.lgt', False)
end;

function BPExePath: String;
var
  BPDIR: String;
begin
  if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\', 'BPDIR', BPDIR) then
    Result := BPDIR + '\bp.bat'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetBPExePath(Param: String): String;
var
  Warning: String;
begin
  Result := BPExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect B-Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	  MsgBox(Warning, mbError, MB_OK);
  end
end;

function CxExePath: String;
var
  CxDir: String;
begin
  if RegQueryStringValue(HKLM, 'SOFTWARE\CxProlog\', 'CXPROLOG_DIR', CxDir) then
    Result := CxDir + '\cxprolog.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetCxExePath(Param: String): String;
var
  Warning: String;
begin
  Result := CxExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect CxProlog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function Eclipse6ExePath: String;
var
  ECLIPSEDIR: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\IC-Parc\Eclipse\6.1\', 'ECLIPSEDIR', ECLIPSEDIR) then
        Result := ECLIPSEDIR + '\lib\x86_64_nt\eclipse.exe'
    else if RegQueryStringValue(HKLM32, 'Software\IC-Parc\Eclipse\6.1\', 'ECLIPSEDIR', ECLIPSEDIR) then
        Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
    else if RegQueryStringValue(HKLM32, 'Software\IC-Parc\Eclipse\6.0\', 'ECLIPSEDIR', ECLIPSEDIR) then
      Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\IC-Parc\Eclipse\6.1\', 'ECLIPSEDIR', ECLIPSEDIR) then
         Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
       else if RegQueryStringValue(HKLM, 'Software\IC-Parc\Eclipse\6.0\', 'ECLIPSEDIR', ECLIPSEDIR) then
         Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
       else
         Result := 'prolog_compiler_not_installed'
end;

function GetEclipse6ExePath(Param: String): String;
var
  Warning: String;
begin
  Result := Eclipse6ExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect ECLiPSe Prolog 6 installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
    MsgBox(Warning, mbError, MB_OK);
  end
end;

function GPExePath: String;
var
  RootPath: String;
begin
  if RegQueryStringValue(HKCU, 'Software\GnuProlog\', 'RootPath', RootPath) then
    Result := RootPath + '\bin\gprolog.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetGPExePath(Param: String): String;
var
  Warning: String;
begin
  Result := GPExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect GNU Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
    MsgBox(Warning, mbError, MB_OK);
  end
end;

function LeanPrologExePath: String;
begin
  if FileExists(ExpandConstant('{pf}') + '\LeanProlog\lprolog.bat') then
    Result := ExpandConstant('{pf}') + '\LeanProlog\lprolog.bat'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetLeanPrologExePath(Param: String): String;
var
  Warning: String;
begin
  Result := LeanPrologExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect Lean Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
    MsgBox(Warning, mbError, MB_OK);
  end
end;

function SICStusExePath: String;
var
  SP_PATH: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\SICS\SICStus4.2_x86-win32-nt-4\', 'SP_PATH', SP_PATH) or
       RegQueryStringValue(HKLM32, 'Software\SICS\SICStus4.2_x86-win32-nt-4\', 'SP_PATH', SP_PATH) or
       RegQueryStringValue(HKLM32, 'Software\SICS\SICStus4.1_x86-win32-nt-4\', 'SP_PATH', SP_PATH)
    then
      Result := SP_PATH + '\bin\spwin.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\SICS\SICStus4.2_x86-win32-nt-4\', 'SP_PATH', SP_PATH) then
    Result := SP_PATH + '\bin\spwin.exe'
  else if RegQueryStringValue(HKLM, 'Software\SICS\SICStus4.1_x86-win32-nt-4\', 'SP_PATH', SP_PATH) then
    Result := SP_PATH + '\bin\spwin.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetSICStusExePath(Param: String): String;
var
  Warning: String;
begin
  Result := SICStusExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect SICStus Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function SWIConExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM64, 'Software\SWI\Prolog\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plcon.exe') then
        Result := Home + '\bin\plcon.exe'
      else if FileExists(Home + '\bin\swipl.exe') then
        Result := Home + '\bin\swipl.exe'
      else
        Result := 'prolog_compiler_not_installed'
  else
    if RegQueryStringValue(HKLM, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plcon.exe') then
        Result := Home + '\bin\plcon.exe'
      else if FileExists(Home + '\bin\swipl.exe') then
        Result := Home + '\bin\swipl.exe'
      else
        Result := 'prolog_compiler_not_installed'
end;

function GetSWIConExePath(Param: String): String;
var
  Warning: String;
begin
  Result := SWIConExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect SWI-Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK)
  end
end;

function SWIWinExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM64, 'Software\SWI\Prolog\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plwin.exe') then
        Result := Home + '\bin\plwin.exe'
      else if FileExists(Home + '\bin\swipl-win.exe') then
        Result := Home + '\bin\swipl-win.exe'
      else
        Result := 'prolog_compiler_not_installed'
  else
    if RegQueryStringValue(HKLM, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plwin.exe') then
        Result := Home + '\bin\plwin.exe'
      else if FileExists(Home + '\bin\swipl-win.exe') then
        Result := Home + '\bin\swipl-win.exe'
      else
        Result := 'prolog_compiler_not_installed'
end;

function GetSWIWinExePath(Param: String): String;
var
  Warning: String;
begin
  Result := SWIWinExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect SWI-Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK)
  end
end;

function XSBExePath: String;
var
  XSB_DIR: String;
begin
  if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\', 'XSB_DIR', XSB_DIR) then
    if IsWin64 and FileExists(XSB_DIR + '\config\x64-pc-windows\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x64-pc-windows\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\x86-pc-windows\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x86-pc-windows\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\i686-pc-cygwin\bin\xsb.exe') then
      Result := XSB_DIR + '\config\i686-pc-cygwin\bin\xsb.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetXSBExePath(Param: String): String;
var
  Warning: String;
begin
  Result := XSBExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect XSB installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function XSBMTExePath: String;
var
  XSB_DIR: String;
begin
  if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\', 'XSB_DIR', XSB_DIR) then
    if IsWin64 and FileExists(XSB_DIR + '\config\x64-pc-windows-mt\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x64-pc-windows-mt\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\x86-pc-windows-mt\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x86-pc-windows-mt\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\i686-pc-cygwin-mt\bin\xsb.exe') then
      Result := XSB_DIR + '\config\i686-pc-cygwin-mt\bin\xsb.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetXSBMTExePath(Param: String): String;
var
  Warning: String;
begin
  Result := XSBMTExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect XSB-MT installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function YAPConExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap.exe'
    else if RegQueryStringValue(HKLM32, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\YAP\Prolog\', 'home', Home) then
    Result := Home + '\bin\yap.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetYAPConExePath(Param: String): String;
var
  Warning: String;
begin
  Result := YAPConExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect YAP installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function YAPWinExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap-win.exe'
    else if RegQueryStringValue(HKLM32, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap-win.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\YAP\Prolog\', 'home', Home) then
    Result := Home + '\bin\yap-win.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetYAPWinExePath(Param: String): String;
var
  Warning: String;
begin
  Result := YAPWinExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect YAP installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function NoBackEndPrologCompilerInstalled: Boolean;
begin
    Result :=
      (BPExePath = 'prolog_compiler_not_installed') and
      (CxExePath = 'prolog_compiler_not_installed') and
      (Eclipse6ExePath = 'prolog_compiler_not_installed') and
      (GPExePath = 'prolog_compiler_not_installed') and
      (SICStusExePath = 'prolog_compiler_not_installed') and
      (SWIConExePath = 'prolog_compiler_not_installed') and
      (SWIWinExePath = 'prolog_compiler_not_installed') and
      (XSBExePath = 'prolog_compiler_not_installed') and
      (XSBMTExePath = 'prolog_compiler_not_installed') and
      (YAPConExePath = 'prolog_compiler_not_installed') and
      (YAPWinExePath = 'prolog_compiler_not_installed')
end;

procedure InitializeWizard;
var
  Version, InstalledVersion: Cardinal;
  LOGTALKHOME, LOGTALKUSER: String;
begin
  if IsAdminLoggedOn then
    if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'LOGTALKHOME', LOGTALKHOME) then
      WizardForm.DirEdit.Text := LOGTALKHOME
    else
      WizardForm.DirEdit.Text := ExpandConstant('{pf}') + '\Logtalk'
  else if RegQueryStringValue(HKCU, 'Environment', 'LOGTALKHOME', LOGTALKHOME) then
    WizardForm.DirEdit.Text := LOGTALKHOME
  else
    WizardForm.DirEdit.Text := ExpandConstant('{localappdata}') + '\Logtalk';
  Explanation := 'Select the folder in which Setup should install Logtalk user files, then click Next.'
                 + Chr(13) + Chr(13)
                 + 'These files allows each user to independently customize Logtalk and to freely modify the provided libraries, programming examples, and other supporting files.'
                 + Chr(13) + Chr(13)
                 + 'A copy of these files must exist in the user home folder in order to use the Logtalk-Prolog integration scripts available from the Start Menu program group "Logtalk".'
                 + Chr(13) + Chr(13)
                 + 'Addtional end-users may use this installer to make a copy of these files on their home folders after a full installation of Logtalk.';
  LgtUserDirPage := CreateInputDirPage(wpSelectDir,
    'Select folder for Logtalk user files', 'Where should Logtalk user files be installed?',
    Explanation,
    False, 'New Folder');
  LgtUserDirPage.Add('');
  if RegQueryStringValue(HKCU, 'Environment', 'LOGTALKUSER', LOGTALKUSER) then
    LgtUserDirPage.Values[0] := LOGTALKUSER
  else
    LgtUserDirPage.Values[0] := ExpandConstant('{userdocs}') + '\Logtalk';
  if not IsAdminLoggedOn and RegQueryDWordValue(HKLM, 'Software\Logtalk', 'Version', Version) then
  begin
    Warning := 'You are running this installer from a non-administrative account.'
               + Chr(13) + Chr(13)
               + 'The base Logtalk system is already installed by an administrator. You may simply setup Logtalk for you as an end-user by choosing to install only the user-level files. In alternative, you may perform a full installation.'
               + Chr(13) + Chr(13)
               + 'If Logtalk is already set for you, this installer will make a backup copy of your current files (if you choose the same installation folder) and will restore all user files to their default, pristine state.';
    WarningPage := CreateOutputMsgPage(wpWelcome, 'Information', 'Please read the following important information before continuing.', Warning);
    WizardForm.TypesCombo.ItemIndex := 2;
    WizardForm.TypesCombo.OnChange(WizardForm.TypesCombo)
  end;
  if RegQueryDWordValue(HKCU, 'Software\Logtalk', 'Version', Version) then
    InstalledVersion := Version
  else if RegQueryDWordValue(HKLM, 'Software\Logtalk', 'Version', Version) then
    InstalledVersion := Version
  else if RegQueryStringValue(HKCU, 'Environment', 'LOGTALKHOME', LOGTALKHOME) and DirExists(LOGTALKHOME) then
    InstalledVersion := 0
  else if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'LOGTALKHOME', LOGTALKHOME) and DirExists(LOGTALKHOME) then
    InstalledVersion := 0
  else
    InstalledVersion := -1;
  if (InstalledVersion >= 0) and (InstalledVersion < {#MyAppVerNumberInteger}) then
  begin
    Warning := 'Your Logtalk user directory is outdated!'
               + Chr(13) + Chr(13)
               + 'You must updade your Logtalk user folder by performing a full installation.'
               + Chr(13) + Chr(13)
               + 'All aditional Logtalk users on your computer must also use this installer to update their Logtalk user folders.';
    WarningPage := CreateOutputMsgPage(wpWelcome, 'Warning', 'Logtalk user folder update required.', Warning)
  end;
  if NoBackEndPrologCompilerInstalled then
  begin
    Error := 'No compatible Prolog compiler found!'
             + Chr(13) + Chr(13)
             + 'Logtalk requires a compatible Prolog compiler to be installed in order to run. Logtalk uses a Prolog compiler as a back-end compiler.'
             + Chr(13) + Chr(13)
             + 'You must rerun the Logtalk installer after installing a compatible Prolog compiler.';
    ErrorPage := CreateOutputMsgPage(wpSelectDir, 'Warning', 'No compatible Prolog compiler found!', Error)
  end
end;

; This file is part of Logtalk <http://logtalk.org/>
; Copyright (c) 1998-2013 Paulo Moura <pmoura@logtalk.org>
;
; Logtalk is free software. You can redistribute it and/or modify it under
; the terms of the FSF GNU General Public License 3  (plus some additional
; terms per section 7).        Consult the `LICENSE.txt` file for details.

#define MyAppName "Logtalk"
#define MyAppPublisher "Logtalk.org"
#define MyAppURL "http://logtalk.org"
#define MyAppUrlName "Logtalk Web Site.url"
#define MyAppRegURL "http://logtalk.org/regform.html"
#define MyAppRegUrlName "Logtalk Registration.url"

#define MyBaseDir "C:\lgt3git"
#define MyAppVer FileRead(FileOpen(MyBaseDir + "\VERSION.txt"))
#define MyAppVerNumberString StringChange(MyAppVer, ".", "")
#define MyAppVerNumberInteger Int(MyAppVerNumberString)

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppName} {#MyAppVer}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ChangesEnvironment=yes
ChangesAssociations=yes
DefaultDirName={pf}\Logtalk
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
LicenseFile={#MyBaseDir}\scripts\windows\LICENSE.rtf
InfoBeforeFile={#MyBaseDir}\scripts\windows\README.rtf
; SetupIconFile={#MyBaseDir}\scripts\windows\logtalk.ico
OutputBaseFilename=lgt{#MyAppVerNumberString}
Compression=lzma
SolidCompression=yes
PrivilegesRequired=none

VersionInfoVersion={#MyAppVer}
VersionInfoCopyright= Paulo Moura, Copyright (c) 1998-2013

AllowRootDirectory=yes
UninstallFilesDir="{userdocs}\Logtalk uninstaller"

MinVersion=0,5.0

[Types]
Name: "full"; Description: "Full installation"
Name: "base"; Description: "Base system installation"
Name: "user"; Description: "User files installation"
Name: "prolog"; Description: "Prolog integration shortcuts"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "base"; Description: "Base system (compiler/runtime, Prolog integration files, manuals)"; Types: full base custom; Flags: disablenouninstallwarning
Name: "user"; Description: "User files (libraries, examples, and other support files)"; Types: full user custom; Flags: checkablealone disablenouninstallwarning
Name: "user\backup"; Description: "Backup current Logtalk user folder"; Types: full user custom; Flags: disablenouninstallwarning
Name: "prolog"; Description: "Prolog integration (back-end compiler support)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\bp"; Description: "B-Prolog integration (version 7.8 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\cxprolog"; Description: "CxProlog integration (version 0.97.6 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\eclipse"; Description: "ECLiPSe integration (version 6.0#141 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\gprolog"; Description: "GNU Prolog integration (version 1.4.1 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\lean"; Description: "Lean Prolog Prolog integration (version 3.7.10 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\sicstus"; Description: "SICStus Prolog integration (version 4.1.0 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\swicon"; Description: "SWI-Prolog (console) integration (version 6.0.0 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\swiwin"; Description: "SWI-Prolog (window) integration (version 6.0.0 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\xsb"; Description: "XSB integration (version 3.3 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\xsbmt"; Description: "XSB-MT integration (version 3.3 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\yap"; Description: "YAP (console) integration (version 6.0.2 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning
Name: "prolog\yap"; Description: "YAP (window) integration (version 6.3.2 or later)"; Types: full prolog custom; Flags: disablenouninstallwarning

[Tasks]
Name: registration; Description: "&Register {#MyAppName} (opens a web page; requires an Internet connection)"; Components: base
Name: shortcut; Description: "&Create a desktop shortcut to the Logtalk user folder"; Components: user

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

[Messages]
BeveledLabel=Logtalk 3.00.0  Paulo Moura, Copyright (c) 1998-2013

[Dirs]
Name: {code:GetLgtUserDir}; Components: user; Flags: uninsneveruninstall
Name: "{userdocs}\Logtalk uninstaller"

[Files]
Source: "{#MyBaseDir}\*"; Excludes: "*.md,.*"; DestDir: "{app}"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyBaseDir}\ACKNOWLEDGMENTS.md"; DestDir: "{app}"; DestName: "ACKNOWLEDGMENTS.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\CUSTOMIZE.md"; DestDir: "{app}"; DestName: "CUSTOMIZE.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\INSTALL.md"; DestDir: "{app}"; DestName: "INSTALL.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\QUICK_START.md"; DestDir: "{app}"; DestName: "QUICK_START.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\README.md"; DestDir: "{app}"; DestName: "README.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\RELEASE_NOTES.md"; DestDir: "{app}"; DestName: "RELEASE_NOTES.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#MyBaseDir}\UPGRADING.md"; DestDir: "{app}"; DestName: "UPGRADING.txt"; Components: base; Flags: ignoreversion skipifsourcedoesntexist

Source: "{#MyBaseDir}\contributions\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\contributions"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\examples\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\examples"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\library\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\library"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\scratch\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\scratch"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "{#MyBaseDir}\tools\*"; Excludes: ".*"; DestDir: "{code:GetLgtUserDir}\tools"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall

Source: "{#MyBaseDir}\settings-sample.lgt"; DestDir: "{code:GetLgtUserDir}"; DestName: "settings-sample.lgt"; Components: user; Flags: ignoreversion uninsneveruninstall
Source: "{#MyBaseDir}\VERSION.txt"; DestDir: "{code:GetLgtUserDir}"; DestName: "VERSION.txt"; Components: user; Flags: ignoreversion uninsneveruninstall

Source: "{#MyBaseDir}\scripts\*.bat"; DestDir: "{win}"; Components: base; Flags: ignoreversion; Check: IsAdminLoggedOn
Source: "{#MyBaseDir}\tools\lgtdoc\xml\*.bat"; DestDir: "{win}"; Components: base; Flags: ignoreversion; Check: IsAdminLoggedOn

[INI]
Filename: "{app}\{#MyAppUrlName}"; Section: "InternetShortcut"; Key: "URL"; String: "{#MyAppURL}"; Components: base
Filename: "{app}\{#MyAppRegUrlName}"; Section: "InternetShortcut"; Key: "URL"; String: "{#MyAppRegURL}"; Components: base

[Icons]
Name: "{group}\Bibliography"; Filename: "{app}\BIBLIOGRAPHY.bib"; Components: base
Name: "{group}\Documentation"; Filename: "{app}\manuals\index.html"; Components: base
Name: "{group}\License"; Filename: "{app}\LICENSE.txt"; Components: base
Name: "{group}\Release Notes"; Filename: "{app}\RELEASE_NOTES.txt"; Components: base
Name: "{group}\Read Me"; Filename: "{app}\README.txt"; Components: base
Name: "{group}\Customization instructions"; Filename: "{app}\CUSTOMIZE.txt"; Components: base
Name: "{group}\Default settings"; Filename: "%LOGTALKUSER%\settings-sample.lgt"; Components: base

Name: "{group}\Web Site"; Filename: "{#MyAppUrl}"; Components: base

Name: "{group}\Logtalk - B-Prolog"; Filename: "{code:GetBPExePath}"; Parameters: "-i ""$LOGTALKHOME/integration/logtalk_bp.pl"""; Comment: "Runs Logtalk with B-Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\bp; Flags: createonlyiffileexists

Name: "{group}\Logtalk - CxProlog"; Filename: "{code:GetCxExePath}"; Parameters: "--script ""%LOGTALKHOME%\\integration\\logtalk_cx.pl"""; Comment: "Runs Logtalk with CxProlog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\cxprolog; Flags: createonlyiffileexists

Name: "{group}\Logtalk - ECLiPSe 6"; Filename: "{code:GetEclipse6ExePath}"; Parameters: "-b ""$LOGTALKHOME/integration/logtalk_eclipse.pl"""; Comment: "Runs Logtalk with ECLiPSe 6"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\eclipse; Flags: createonlyiffileexists

Name: "{group}\Logtalk - GNU Prolog"; Filename: "{code:GetGPExePath}"; Parameters: "--init-goal ""['$LOGTALKHOME/integration/logtalk_gp.pl']"""; Comment: "Runs Logtalk with GNU Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\gprolog; Flags: createonlyiffileexists

Name: "{group}\Logtalk - Lean Prolog"; Filename: "{code:GetLeanPrologExePath}"; Parameters: """['$LOGTALKHOME/integration/logtalk_lean']"""; Comment: "Runs Logtalk with Lean Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\lean; Flags: createonlyiffileexists

Name: "{group}\Logtalk - SICStus Prolog"; Filename: "{code:GetSICStusExePath}"; Parameters: "-l ""%LOGTALKHOME%\integration\logtalk_sicstus.pl"""; Comment: "Runs Logtalk with SICStus Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\sicstus; Flags: createonlyiffileexists

Name: "{group}\Logtalk - SWI-Prolog (console)"; Filename: "{code:GetSWIConExePath}"; Parameters: "-s ""%LOGTALKHOME%\integration\logtalk_swi.pl"""; Comment: "Runs Logtalk with SWI-Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\swicon; Flags: createonlyiffileexists

Name: "{group}\Logtalk - SWI-Prolog (window)"; Filename: "{code:GetSWIWinExePath}"; Parameters: "-s ""%LOGTALKHOME%\integration\logtalk_swi.pl"""; Comment: "Runs Logtalk with SWI-Prolog"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\swiwin; Flags: createonlyiffileexists

Name: "{group}\Logtalk - XSB"; Filename: "{code:GetXSBExePath}"; Parameters: "-l -e ""['%LOGTALKHOME%\\integration\\logtalk_xsb.pl']."""; Comment: "Runs Logtalk with XSB"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\xsb; Flags: createonlyiffileexists

Name: "{group}\Logtalk - XSB-MT"; Filename: "{code:GetXSBMTExePath}"; Parameters: "-l -e ""['%LOGTALKHOME%\\integration\\logtalk_xsbmt.pl']."""; Comment: "Runs Logtalk with XSB-MT"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\xsbmt; Flags: createonlyiffileexists

Name: "{group}\Logtalk - YAP (console)"; Filename: "{code:GetYAPConExePath}"; Parameters: "-l ""$LOGTALKHOME/integration/logtalk_yap.pl"""; Comment: "Runs Logtalk with YAP"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\yap; Flags: createonlyiffileexists

Name: "{group}\Logtalk - YAP (window)"; Filename: "{code:GetYAPWinExePath}"; Parameters: "-l ""$LOGTALKHOME/integration/logtalk_yap.pl"""; Comment: "Runs Logtalk with YAP"; WorkingDir: "%LOGTALKUSER%"; Components: prolog\yap; Flags: createonlyiffileexists

Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; Components: base

Name: "{code:GetLgtUserDir}\Bibliography"; Filename: "{app}\BIBLIOGRAPHY.bib"; Components: user
Name: "{code:GetLgtUserDir}\License"; Filename: "{app}\LICENSE.txt"; Components: user
Name: "{code:GetLgtUserDir}\Release Notes"; Filename: "{app}\RELEASE_NOTES.txt"; Components: user
Name: "{code:GetLgtUserDir}\Read Me"; Filename: "{app}\README.txt"; Components: user
Name: "{code:GetLgtUserDir}\Customization instructions"; Filename: "{app}\CUSTOMIZE.txt"; Components: user
Name: "{code:GetLgtUserDir}\adapters"; Filename: "{app}\adapters"; Components: user
Name: "{code:GetLgtUserDir}\manuals"; Filename: "{app}\manuals"; Components: user
Name: "{code:GetLgtUserDir}\paths"; Filename: "{app}\paths"; Components: user
Name: "{code:GetLgtUserDir}\coding"; Filename: "{app}\coding"; Components: user

Name: "{userdesktop}\Logtalk user files"; Filename: "{code:GetLgtUserDir}"; Components: user; Tasks: shortcut

[Registry]
; admin users
Root: HKLM; Subkey: "Software\Logtalk"; ValueType: dword; ValueName: "Version"; ValueData: "{#MyAppVerNumberInteger}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "LOGTALKHOME"; ValueData: "{app}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKUSER"; ValueData: "{code:GetLgtUserDir}"; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKLM; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; Components: base; Flags: uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKLM; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; ValueType: string; ValueName: "Extension"; ValueData: ".lgt"; Components: base; Flags: deletevalue uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKCR; Subkey: ".lgt"; ValueType: string; ValueName: ""; ValueData: "LogtalkSourceFile"; Components: base; Flags: uninsdeletevalue; Check: IsAdminLoggedOn
Root: HKCR; Subkey: "LogtalkSourceFile"; ValueType: string; ValueName: ""; ValueData: "Logtalk source file"; Components: base; Flags: uninsdeletekey; Check: IsAdminLoggedOn
; non-admin users
Root: HKCU; Subkey: "Software\Logtalk"; ValueType: dword; ValueName: "Version"; ValueData: "{#MyAppVerNumberInteger}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKHOME"; ValueData: "{app}"; Components: base; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKUSER"; ValueData: "{code:GetLgtUserDir}"; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; Components: base; Flags: uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\MIME\Database\Content Type\text/x-logtalk"; ValueType: string; ValueName: "Extension"; ValueData: ".lgt"; Components: base; Flags: deletevalue uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\.lgt"; ValueType: string; ValueName: ""; ValueData: "LogtalkSourceFile"; Components: base; Flags: uninsdeletevalue; Check: not IsAdminLoggedOn
Root: HKCU; Subkey: "SOFTWARE\Classes\LogtalkSourceFile"; ValueType: string; ValueName: ""; ValueData: "Logtalk source file"; Components: base; Flags: uninsdeletekey; Check: not IsAdminLoggedOn

[Run]
Filename: "{app}\RELEASE_NOTES.txt"; Description: "View the release notes"; Components: base; Flags: postinstall shellexec skipifsilent
Filename: "{app}\CUSTOMIZE.txt"; Description: "Read the customization instructions for completing your setup"; Components: base; Flags: postinstall shellexec skipifsilent

Filename: "{app}\{#MyAppRegUrlName}"; Components: base; Flags: shellexec nowait; Tasks: registration

[UninstallDelete]
Type: filesandordirs; Name: "{app}"; Components: base
Type: filesandordirs; Name: "{group}"; Components: base

[Code]
var
  LgtUserDirPage: TInputDirWizardPage;
  WarningPage, ErrorPage: TOutputMsgWizardPage;
  Explanation, Warning, Error, BackupFolder: String;

function GetLgtUserDir(Param: String): String;
begin
  Result := LgtUserDirPage.Values[0]
end;

function GetCurrentDate(Param: String): String;
begin
  Result := GetDateTimeString('dddddd tt', '-', '-')
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  NewFolder: String;
begin
  NewFolder := LgtUserDirPage.Values[0];
  if (CurStep = ssInstall) and DirExists(NewFolder) and (pos('backup', WizardSelectedComponents(False)) > 0) then begin
    BackupFolder := NewFolder + '-backup-' + GetDateTimeString('yyyy-mm-dd-hhnnss', '-', ':');
    RenameFile(NewFolder, BackupFolder)
  end
  else if (CurStep = ssPostInstall) and FileExists(BackupFolder + '\settings.lgt') then
    FileCopy(BackupFolder + '\settings.lgt', NewFolder + '\settings.lgt', False)
end;

function BPExePath: String;
var
  BPDIR: String;
begin
  if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\', 'BPDIR', BPDIR) then
    Result := BPDIR + '\bp.bat'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetBPExePath(Param: String): String;
var
  Warning: String;
begin
  Result := BPExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect B-Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	  MsgBox(Warning, mbError, MB_OK);
  end
end;

function CxExePath: String;
var
  CxDir: String;
begin
  if RegQueryStringValue(HKLM, 'SOFTWARE\CxProlog\', 'CXPROLOG_DIR', CxDir) then
    Result := CxDir + '\cxprolog.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetCxExePath(Param: String): String;
var
  Warning: String;
begin
  Result := CxExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect CxProlog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function Eclipse6ExePath: String;
var
  ECLIPSEDIR: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\IC-Parc\Eclipse\6.1\', 'ECLIPSEDIR', ECLIPSEDIR) then
        Result := ECLIPSEDIR + '\lib\x86_64_nt\eclipse.exe'
    else if RegQueryStringValue(HKLM32, 'Software\IC-Parc\Eclipse\6.1\', 'ECLIPSEDIR', ECLIPSEDIR) then
        Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
    else if RegQueryStringValue(HKLM32, 'Software\IC-Parc\Eclipse\6.0\', 'ECLIPSEDIR', ECLIPSEDIR) then
      Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\IC-Parc\Eclipse\6.1\', 'ECLIPSEDIR', ECLIPSEDIR) then
         Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
       else if RegQueryStringValue(HKLM, 'Software\IC-Parc\Eclipse\6.0\', 'ECLIPSEDIR', ECLIPSEDIR) then
         Result := ECLIPSEDIR + '\lib\i386_nt\eclipse.exe'
       else
         Result := 'prolog_compiler_not_installed'
end;

function GetEclipse6ExePath(Param: String): String;
var
  Warning: String;
begin
  Result := Eclipse6ExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect ECLiPSe Prolog 6 installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
    MsgBox(Warning, mbError, MB_OK);
  end
end;

function GPExePath: String;
var
  RootPath: String;
begin
  if RegQueryStringValue(HKCU, 'Software\GnuProlog\', 'RootPath', RootPath) then
    Result := RootPath + '\bin\gprolog.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetGPExePath(Param: String): String;
var
  Warning: String;
begin
  Result := GPExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect GNU Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
    MsgBox(Warning, mbError, MB_OK);
  end
end;

function LeanPrologExePath: String;
begin
  if FileExists(ExpandConstant('{pf}') + '\LeanProlog\lprolog.bat') then
    Result := ExpandConstant('{pf}') + '\LeanProlog\lprolog.bat'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetLeanPrologExePath(Param: String): String;
var
  Warning: String;
begin
  Result := LeanPrologExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect Lean Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
    MsgBox(Warning, mbError, MB_OK);
  end
end;

function SICStusExePath: String;
var
  SP_PATH: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\SICS\SICStus4.2_x86-win32-nt-4\', 'SP_PATH', SP_PATH) or
       RegQueryStringValue(HKLM32, 'Software\SICS\SICStus4.2_x86-win32-nt-4\', 'SP_PATH', SP_PATH) or
       RegQueryStringValue(HKLM32, 'Software\SICS\SICStus4.1_x86-win32-nt-4\', 'SP_PATH', SP_PATH)
    then
      Result := SP_PATH + '\bin\spwin.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\SICS\SICStus4.2_x86-win32-nt-4\', 'SP_PATH', SP_PATH) then
    Result := SP_PATH + '\bin\spwin.exe'
  else if RegQueryStringValue(HKLM, 'Software\SICS\SICStus4.1_x86-win32-nt-4\', 'SP_PATH', SP_PATH) then
    Result := SP_PATH + '\bin\spwin.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetSICStusExePath(Param: String): String;
var
  Warning: String;
begin
  Result := SICStusExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect SICStus Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function SWIConExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM64, 'Software\SWI\Prolog\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plcon.exe') then
        Result := Home + '\bin\plcon.exe'
      else if FileExists(Home + '\bin\swipl.exe') then
        Result := Home + '\bin\swipl.exe'
      else
        Result := 'prolog_compiler_not_installed'
  else
    if RegQueryStringValue(HKLM, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plcon.exe') then
        Result := Home + '\bin\plcon.exe'
      else if FileExists(Home + '\bin\swipl.exe') then
        Result := Home + '\bin\swipl.exe'
      else
        Result := 'prolog_compiler_not_installed'
end;

function GetSWIConExePath(Param: String): String;
var
  Warning: String;
begin
  Result := SWIConExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect SWI-Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK)
  end
end;

function SWIWinExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM64, 'Software\SWI\Prolog\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM32, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plwin.exe') then
        Result := Home + '\bin\plwin.exe'
      else if FileExists(Home + '\bin\swipl-win.exe') then
        Result := Home + '\bin\swipl-win.exe'
      else
        Result := 'prolog_compiler_not_installed'
  else
    if RegQueryStringValue(HKLM, 'Software\SWI\Prolog64\', 'home', Home) or
       RegQueryStringValue(HKLM, 'Software\SWI\Prolog\', 'home', Home)
    then
      if FileExists(Home + '\bin\plwin.exe') then
        Result := Home + '\bin\plwin.exe'
      else if FileExists(Home + '\bin\swipl-win.exe') then
        Result := Home + '\bin\swipl-win.exe'
      else
        Result := 'prolog_compiler_not_installed'
end;

function GetSWIWinExePath(Param: String): String;
var
  Warning: String;
begin
  Result := SWIWinExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect SWI-Prolog installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK)
  end
end;

function XSBExePath: String;
var
  XSB_DIR: String;
begin
  if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\', 'XSB_DIR', XSB_DIR) then
    if IsWin64 and FileExists(XSB_DIR + '\config\x64-pc-windows\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x64-pc-windows\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\x86-pc-windows\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x86-pc-windows\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\i686-pc-cygwin\bin\xsb.exe') then
      Result := XSB_DIR + '\config\i686-pc-cygwin\bin\xsb.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetXSBExePath(Param: String): String;
var
  Warning: String;
begin
  Result := XSBExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect XSB installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function XSBMTExePath: String;
var
  XSB_DIR: String;
begin
  if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\', 'XSB_DIR', XSB_DIR) then
    if IsWin64 and FileExists(XSB_DIR + '\config\x64-pc-windows-mt\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x64-pc-windows-mt\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\x86-pc-windows-mt\bin\xsb.exe') then
      Result := XSB_DIR + '\config\x86-pc-windows-mt\bin\xsb.exe'
    else if FileExists(XSB_DIR + '\config\i686-pc-cygwin-mt\bin\xsb.exe') then
      Result := XSB_DIR + '\config\i686-pc-cygwin-mt\bin\xsb.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetXSBMTExePath(Param: String): String;
var
  Warning: String;
begin
  Result := XSBMTExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect XSB-MT installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function YAPConExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap.exe'
    else if RegQueryStringValue(HKLM32, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\YAP\Prolog\', 'home', Home) then
    Result := Home + '\bin\yap.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetYAPConExePath(Param: String): String;
var
  Warning: String;
begin
  Result := YAPConExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect YAP installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function YAPWinExePath: String;
var
  Home: String;
begin
  if IsWin64 then
    if RegQueryStringValue(HKLM64, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap-win.exe'
    else if RegQueryStringValue(HKLM32, 'Software\YAP\Prolog64\', 'home', Home) then
      Result := Home + '\bin\yap-win.exe'
    else
      Result := 'prolog_compiler_not_installed'
  else if RegQueryStringValue(HKLM, 'Software\YAP\Prolog\', 'home', Home) then
    Result := Home + '\bin\yap-win.exe'
  else
    Result := 'prolog_compiler_not_installed'
end;

function GetYAPWinExePath(Param: String): String;
var
  Warning: String;
begin
  Result := YAPWinExePath;
  if Result = 'prolog_compiler_not_installed' then
  begin
    Warning := 'Failed to detect YAP installation.' + Chr(13) + 'Logtalk integration shortcut not created.';
	MsgBox(Warning, mbError, MB_OK);
  end
end;

function NoBackEndPrologCompilerInstalled: Boolean;
begin
    Result :=
      (BPExePath = 'prolog_compiler_not_installed') and
      (CxExePath = 'prolog_compiler_not_installed') and
      (Eclipse6ExePath = 'prolog_compiler_not_installed') and
      (GPExePath = 'prolog_compiler_not_installed') and
      (SICStusExePath = 'prolog_compiler_not_installed') and
      (SWIConExePath = 'prolog_compiler_not_installed') and
      (SWIWinExePath = 'prolog_compiler_not_installed') and
      (XSBExePath = 'prolog_compiler_not_installed') and
      (XSBMTExePath = 'prolog_compiler_not_installed') and
      (YAPConExePath = 'prolog_compiler_not_installed') and
      (YAPWinExePath = 'prolog_compiler_not_installed')
end;

procedure InitializeWizard;
var
  Version, InstalledVersion: Cardinal;
  LOGTALKHOME, LOGTALKUSER: String;
begin
  if IsAdminLoggedOn then
    if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'LOGTALKHOME', LOGTALKHOME) then
      WizardForm.DirEdit.Text := LOGTALKHOME
    else
      WizardForm.DirEdit.Text := ExpandConstant('{pf}') + '\Logtalk'
  else if RegQueryStringValue(HKCU, 'Environment', 'LOGTALKHOME', LOGTALKHOME) then
    WizardForm.DirEdit.Text := LOGTALKHOME
  else
    WizardForm.DirEdit.Text := ExpandConstant('{localappdata}') + '\Logtalk';
  Explanation := 'Select the folder in which Setup should install Logtalk user files, then click Next.'
                 + Chr(13) + Chr(13)
                 + 'These files allows each user to independently customize Logtalk and to freely modify the provided libraries, programming examples, and other supporting files.'
                 + Chr(13) + Chr(13)
                 + 'A copy of these files must exist in the user home folder in order to use the Logtalk-Prolog integration scripts available from the Start Menu program group "Logtalk".'
                 + Chr(13) + Chr(13)
                 + 'Addtional end-users may use this installer to make a copy of these files on their home folders after a full installation of Logtalk.';
  LgtUserDirPage := CreateInputDirPage(wpSelectDir,
    'Select folder for Logtalk user files', 'Where should Logtalk user files be installed?',
    Explanation,
    False, 'New Folder');
  LgtUserDirPage.Add('');
  if RegQueryStringValue(HKCU, 'Environment', 'LOGTALKUSER', LOGTALKUSER) then
    LgtUserDirPage.Values[0] := LOGTALKUSER
  else
    LgtUserDirPage.Values[0] := ExpandConstant('{userdocs}') + '\Logtalk';
  if not IsAdminLoggedOn and RegQueryDWordValue(HKLM, 'Software\Logtalk', 'Version', Version) then
  begin
    Warning := 'You are running this installer from a non-administrative account.'
               + Chr(13) + Chr(13)
               + 'The base Logtalk system is already installed by an administrator. You may simply setup Logtalk for you as an end-user by choosing to install only the user-level files. In alternative, you may perform a full installation.'
               + Chr(13) + Chr(13)
               + 'If Logtalk is already set for you, this installer will make a backup copy of your current files (if you choose the same installation folder) and will restore all user files to their default, pristine state.';
    WarningPage := CreateOutputMsgPage(wpWelcome, 'Information', 'Please read the following important information before continuing.', Warning);
    WizardForm.TypesCombo.ItemIndex := 2;
    WizardForm.TypesCombo.OnChange(WizardForm.TypesCombo)
  end;
  if RegQueryDWordValue(HKCU, 'Software\Logtalk', 'Version', Version) then
    InstalledVersion := Version
  else if RegQueryDWordValue(HKLM, 'Software\Logtalk', 'Version', Version) then
    InstalledVersion := Version
  else if RegQueryStringValue(HKCU, 'Environment', 'LOGTALKHOME', LOGTALKHOME) and DirExists(LOGTALKHOME) then
    InstalledVersion := 0
  else if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'LOGTALKHOME', LOGTALKHOME) and DirExists(LOGTALKHOME) then
    InstalledVersion := 0
  else
    InstalledVersion := -1;
  if (InstalledVersion >= 0) and (InstalledVersion < {#MyAppVerNumberInteger}) then
  begin
    Warning := 'Your Logtalk user directory is outdated!'
               + Chr(13) + Chr(13)
               + 'You must updade your Logtalk user folder by performing a full installation.'
               + Chr(13) + Chr(13)
               + 'All aditional Logtalk users on your computer must also use this installer to update their Logtalk user folders.';
    WarningPage := CreateOutputMsgPage(wpWelcome, 'Warning', 'Logtalk user folder update required.', Warning)
  end;
  if NoBackEndPrologCompilerInstalled then
  begin
    Error := 'No compatible Prolog compiler found!'
             + Chr(13) + Chr(13)
             + 'Logtalk requires a compatible Prolog compiler to be installed in order to run. Logtalk uses a Prolog compiler as a back-end compiler.'
             + Chr(13) + Chr(13)
             + 'You must rerun the Logtalk installer after installing a compatible Prolog compiler.';
    ErrorPage := CreateOutputMsgPage(wpSelectDir, 'Warning', 'No compatible Prolog compiler found!', Error)
  end
end;


Bump version number in Inno script for release

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

[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={{2E6818B6-DA37-4D45-8FED-88A6EED6CD08}
AppName=Software Carpentry Windows Installer
AppVersion=0.2
;AppVerName=Software Carpentry Windows Installer 0.2
AppPublisher=Software Carpentry
AppPublisherURL=http://software-carpentry.org
AppSupportURL=http://software-carpentry.org
AppUpdatesURL=http://software-carpentry.org
DefaultDirName={pf}\swc-installer
DefaultGroupName=Software Carpentry Windows Installer
DisableProgramGroupPage=yes
OutputBaseFilename=SWCarpentryInstaller
SetupIconFile=software-carpentry-logo.ico
Compression=lzma
SolidCompression=yes

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

[Files]
Source: "dist\swc-windows-installer.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\Software Carpentry Windows Installer"; Filename: "{app}\swc-windows-installer.exe"

[Run]
Filename: "{app}\swc-windows-installer.exe"; Description: "{cm:LaunchProgram,Software Carpentry Windows Installer}"; Flags: nowait postinstall skipifsilent

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

[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={{2E6818B6-DA37-4D45-8FED-88A6EED6CD08}
AppName=Software Carpentry Windows Installer
AppVersion=0.1
;AppVerName=Software Carpentry Windows Installer 0.1
AppPublisher=Software Carpentry
AppPublisherURL=http://software-carpentry.org
AppSupportURL=http://software-carpentry.org
AppUpdatesURL=http://software-carpentry.org
DefaultDirName={pf}\swc-installer
DefaultGroupName=Software Carpentry Windows Installer
DisableProgramGroupPage=yes
OutputBaseFilename=SWCarpentryInstaller
SetupIconFile=software-carpentry-logo.ico
Compression=lzma
SolidCompression=yes

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

[Files]
Source: "dist\swc-windows-installer.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\Software Carpentry Windows Installer"; Filename: "{app}\swc-windows-installer.exe"

[Run]
Filename: "{app}\swc-windows-installer.exe"; Description: "{cm:LaunchProgram,Software Carpentry Windows Installer}"; Flags: nowait postinstall skipifsilent


Version bump

Version bump

#define MyAppName "NVM for Windows"
#define MyAppShortName "nvm"
#define MyAppLCShortName "nvm"
#define MyAppVersion "1.0.3"
#define MyAppPublisher "Ecor Ventures, LLC"
#define MyAppURL "http://github.com/coreybutler/nvm"
#define MyAppExeName "nvm.exe"
#define MyIcon "nodejs.ico"
#define ProjectRoot "C:\Users\Corey\Documents\workspace\Experiments\nvm"

[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.)
PrivilegesRequired=admin
AppId=40078385-F676-4C61-9A9C-F9028599D6D3
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={userappdata}\{#MyAppShortName}
DisableDirPage=no
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile={#ProjectRoot}\LICENSE
OutputDir={#ProjectRoot}\dist\{#MyAppVersion}
OutputBaseFilename={#MyAppLCShortName}-setup
SetupIconFile={#ProjectRoot}\{#MyIcon}
Compression=lzma
SolidCompression=yes
ChangesEnvironment=yes
DisableProgramGroupPage=yes
ArchitecturesInstallIn64BitMode=x64 ia64
UninstallDisplayIcon={app}\{#MyIcon}
AppCopyright=Copyright (C) 2014 Corey Butler.

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

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

[Files]
Source: "{#ProjectRoot}\bin\*"; DestDir: "{app}"; BeforeInstall: PreInstall; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{#MyIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"

[Code]
var
  SymlinkPage: TInputDirWizardPage;

function IsDirEmpty(dir: string): Boolean;
var
  FindRec: TFindRec;
  ct: Integer;
begin
  ct := 0;
  if FindFirst(ExpandConstant(dir + '\*'), FindRec) then
  try
    repeat
      if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
        ct := ct+1;
    until
      not FindNext(FindRec);
  finally
    FindClose(FindRec);
    Result := ct = 0;
  end;
end;

//function getInstalledVErsions(dir: string):
var
  nodeInUse: string;

function TakeControl(np: string; nv: string): string;
var
  path: string;
begin
  // Move the existing node.js installation directory to the nvm root & update the path
  RenameFile(np,ExpandConstant('{app}')+'\'+nv);

  RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'Path', path);

  StringChangeEx(path,np+'\','',True);
  StringChangeEx(path,np,'',True);
  StringChangeEx(path,np+';;',';',True);

  RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);

  RegQueryStringValue(HKEY_CURRENT_USER,
    'Environment',
    'Path', path);

  StringChangeEx(path,np+'\','',True);
  StringChangeEx(path,np,'',True);
  StringChangeEx(path,np+';;',';',True);

  RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);

  nodeInUse := ExpandConstant('{app}')+'\'+nv;

end;

function Ansi2String(AString:AnsiString):String;
var
 i : Integer;
 iChar : Integer;
 outString : String;
begin
 outString :='';
 for i := 1 to Length(AString) do
 begin
  iChar := Ord(AString[i]); //get int value
  outString := outString + Chr(iChar);
 end;

 Result := outString;
end;

procedure PreInstall();
var
  TmpResultFile, TmpJS, NodeVersion, NodePath: string;
  stdout: Ansistring;
  ResultCode: integer;
  msg1, msg2, msg3, dir1: Boolean;
begin
  // Create a file to check for Node.JS
  TmpJS := ExpandConstant('{tmp}') + '\nvm_check.js';
  SaveStringToFile(TmpJS, 'console.log(require("path").dirname(process.execPath));', False);

  // Execute the node file and save the output temporarily
  TmpResultFile := ExpandConstant('{tmp}') + '\nvm_node_check.txt';
  Exec(ExpandConstant('{cmd}'), '/C node "'+TmpJS+'" > "' + TmpResultFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  DeleteFile(TmpJS)

  // Process the results
  LoadStringFromFile(TmpResultFile,stdout);
  NodePath := Trim(Ansi2String(stdout));
  if DirExists(NodePath) then begin
    Exec(ExpandConstant('{cmd}'), '/C node -v > "' + TmpResultFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
    LoadStringFromFile(TmpResultFile, stdout);
    NodeVersion := Trim(Ansi2String(stdout));
    msg1 := MsgBox('Node '+NodeVersion+' is already installed. Do you want NVM to control this version?', mbConfirmation, MB_YESNO) = IDNO;
    if msg1 then begin
      msg2 := MsgBox('NVM cannot run in parallel with an existing Node.js installation. Node.js must be uninstalled before NVM can be installed, or you must allow NVM to control the existing installation. Do you want NVM to control node '+NodeVersion+'?', mbConfirmation, MB_YESNO) = IDYES;
      if msg2 then begin
        TakeControl(NodePath, NodeVersion);
      end;
      if not msg2 then begin
        DeleteFile(TmpResultFile);
        WizardForm.Close;
      end;
    end;
    if not msg1 then
    begin
      TakeControl(NodePath, NodeVersion);
    end;
  end;

  // Make sure the symlink directory doesn't exist
  if DirExists(SymlinkPage.Values[0]) then begin
    // If the directory is empty, just delete it since it will be recreated anyway.
    dir1 := IsDirEmpty(SymlinkPage.Values[0]);
    if dir1 then begin
      RemoveDir(SymlinkPage.Values[0]);
    end;
    if not dir1 then begin
      msg3 := MsgBox(SymlinkPage.Values[0]+' will be overwritten and all contents will be lost. Do you want to proceed?', mbConfirmation, MB_OKCANCEL) = IDOK;
      if msg3 then begin
        RemoveDir(SymlinkPage.Values[0]);
      end;
      if not msg3 then begin
        //RaiseException('The symlink cannot be created due to a conflict with the existing directory at '+SymlinkPage.Values[0]);
        WizardForm.Close;
      end;
    end;
  end;
end;

procedure InitializeWizard;
begin
  SymlinkPage := CreateInputDirPage(wpSelectDir,
    'Set Node.js Symlink', 'The active version of Node.js will always be available here.',
    'Select the folder in which Setup should create the symlink, then click Next.',
    False, '');
  SymlinkPage.Add('This directory will automatically be added to your system path.');
  SymlinkPage.Values[0] := ExpandConstant('{pf}\nodejs');
end;

function InitializeUninstall(): Boolean;
var
  path: string;
  nvm_symlink: string;
begin
  MsgBox('Removing NVM for Windows will remove the nvm command and all versions of node.js, including global npm modules.', mbInformation, MB_OK);

  // Remove the symlink
  RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'NVM_SYMLINK', nvm_symlink);
  RemoveDir(nvm_symlink);

  // Clean the registry
  RegDeleteValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'NVM_HOME')
  RegDeleteValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'NVM_SYMLINK')
  RegDeleteValue(HKEY_CURRENT_USER,
    'Environment',
    'NVM_HOME')
  RegDeleteValue(HKEY_CURRENT_USER,
    'Environment',
    'NVM_SYMLINK')

  RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'Path', path);

  StringChangeEx(path,'%NVM_HOME%','',True);
  StringChangeEx(path,'%NVM_SYMLINK%','',True);
  StringChangeEx(path,';;',';',True);

  RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);

  RegQueryStringValue(HKEY_CURRENT_USER,
    'Environment',
    'Path', path);

  StringChangeEx(path,'%NVM_HOME%','',True);
  StringChangeEx(path,'%NVM_SYMLINK%','',True);
  StringChangeEx(path,';;',';',True);

  RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);

  Result := True;
end;

// Generate the settings file based on user input & update registry
procedure CurStepChanged(CurStep: TSetupStep);
var
  path: string;
begin
  if CurStep = ssPostInstall then
  begin
    SaveStringToFile(ExpandConstant('{app}\settings.txt'), 'root: ' + ExpandConstant('{app}') + #13#10 + 'path: ' + SymlinkPage.Values[0] + #13#10, False);

    // Add Registry settings
    RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'NVM_HOME', ExpandConstant('{app}'));
    RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'NVM_SYMLINK', SymlinkPage.Values[0]);
    RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'NVM_HOME', ExpandConstant('{app}'));
    RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'NVM_SYMLINK', SymlinkPage.Values[0]);

    // Update system and user PATH if needed
    RegQueryStringValue(HKEY_LOCAL_MACHINE,
      'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
      'Path', path);
    if Pos('%NVM_HOME%',path) = 0 then begin
      path := path+';%NVM_HOME%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
    end;
    if Pos('%NVM_SYMLINK%',path) = 0 then begin
      path := path+';%NVM_SYMLINK%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
    end;
    RegQueryStringValue(HKEY_CURRENT_USER,
      'Environment',
      'Path', path);
    if Pos('%NVM_HOME%',path) = 0 then begin
      path := path+';%NVM_HOME%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
    end;
    if Pos('%NVM_SYMLINK%',path) = 0 then begin
      path := path+';%NVM_SYMLINK%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
    end;
  end;
end;

function getSymLink(o: string): string;
begin
  Result := SymlinkPage.Values[0];
end;

function getCurrentVersion(o: string): string;
begin
  Result := nodeInUse;
end;

function isNodeAlreadyInUse(): boolean;
begin
  Result := Length(nodeInUse) > 0;
end;

[Run]
Filename: "{cmd}"; Parameters: "/C ""mklink /D ""{code:getSymLink}"" ""{code:getCurrentVersion}"""" "; Check: isNodeAlreadyInUse; Flags: runhidden;
Filename: "{cmd}"; Parameters: "/K ""set PATH={app};%PATH% && cls && nvm"""; Flags: runasoriginaluser postinstall;

[UninstallDelete]
Type: files; Name: "{app}\nvm.exe";
Type: files; Name: "{app}\elevate.cmd";
Type: files; Name: "{app}\elevate.vbs";
Type: files; Name: "{app}\nodejs.ico";
Type: files; Name: "{app}\settings.txt";
Type: filesandordirs; Name: "{app}";

#define MyAppName "NVM for Windows"
#define MyAppShortName "nvm"
#define MyAppLCShortName "nvm"
#define MyAppVersion "1.0.1"
#define MyAppPublisher "Ecor Ventures, LLC"
#define MyAppURL "http://github.com/coreybutler/nvm"
#define MyAppExeName "nvm.exe"
#define MyIcon "nodejs.ico"
#define ProjectRoot "C:\Users\Corey\Documents\workspace\Experiments\nvm"

[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.)
PrivilegesRequired=admin
AppId=40078385-F676-4C61-9A9C-F9028599D6D3
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={userappdata}\{#MyAppShortName}
DisableDirPage=no
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile={#ProjectRoot}\LICENSE
OutputDir={#ProjectRoot}\dist\{#MyAppVersion}
OutputBaseFilename={#MyAppLCShortName}-setup
SetupIconFile={#ProjectRoot}\{#MyIcon}
Compression=lzma
SolidCompression=yes
ChangesEnvironment=yes
DisableProgramGroupPage=yes
ArchitecturesInstallIn64BitMode=x64 ia64
UninstallDisplayIcon={app}\{#MyIcon}
AppCopyright=Copyright (C) 2014 Corey Butler.

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

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

[Files]
Source: "{#ProjectRoot}\bin\*"; DestDir: "{app}"; BeforeInstall: PreInstall; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{#MyIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"

[Code]
var
  SymlinkPage: TInputDirWizardPage;

function IsDirEmpty(dir: string): Boolean;
var
  FindRec: TFindRec;
  ct: Integer;
begin
  ct := 0;
  if FindFirst(ExpandConstant(dir + '\*'), FindRec) then
  try
    repeat
      if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
        ct := ct+1;
    until
      not FindNext(FindRec);
  finally
    FindClose(FindRec);
    Result := ct = 0;
  end;
end;

//function getInstalledVErsions(dir: string):
var
  nodeInUse: string;

function TakeControl(np: string; nv: string): string;
var
  path: string;
begin
  // Move the existing node.js installation directory to the nvm root & update the path
  RenameFile(np,ExpandConstant('{app}')+'\'+nv);

  RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'Path', path);

  StringChangeEx(path,np+'\','',True);
  StringChangeEx(path,np,'',True);
  StringChangeEx(path,np+';;',';',True);

  RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);

  RegQueryStringValue(HKEY_CURRENT_USER,
    'Environment',
    'Path', path);

  StringChangeEx(path,np+'\','',True);
  StringChangeEx(path,np,'',True);
  StringChangeEx(path,np+';;',';',True);

  RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);

  nodeInUse := ExpandConstant('{app}')+'\'+nv;

end;

function Ansi2String(AString:AnsiString):String;
var
 i : Integer;
 iChar : Integer;
 outString : String;
begin
 outString :='';
 for i := 1 to Length(AString) do
 begin
  iChar := Ord(AString[i]); //get int value
  outString := outString + Chr(iChar);
 end;

 Result := outString;
end;

procedure PreInstall();
var
  TmpResultFile, TmpJS, NodeVersion, NodePath: string;
  stdout: Ansistring;
  ResultCode: integer;
  msg1, msg2, msg3, dir1: Boolean;
begin
  // Create a file to check for Node.JS
  TmpJS := ExpandConstant('{tmp}') + '\nvm_check.js';
  SaveStringToFile(TmpJS, 'console.log(require("path").dirname(process.execPath));', False);

  // Execute the node file and save the output temporarily
  TmpResultFile := ExpandConstant('{tmp}') + '\nvm_node_check.txt';
  Exec(ExpandConstant('{cmd}'), '/C node "'+TmpJS+'" > "' + TmpResultFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  DeleteFile(TmpJS)

  // Process the results
  LoadStringFromFile(TmpResultFile,stdout);
  NodePath := Trim(Ansi2String(stdout));
  if DirExists(NodePath) then begin
    Exec(ExpandConstant('{cmd}'), '/C node -v > "' + TmpResultFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
    LoadStringFromFile(TmpResultFile, stdout);
    NodeVersion := Trim(Ansi2String(stdout));
    msg1 := MsgBox('Node '+NodeVersion+' is already installed. Do you want NVM to control this version?', mbConfirmation, MB_YESNO) = IDNO;
    if msg1 then begin
      msg2 := MsgBox('NVM cannot run in parallel with an existing Node.js installation. Node.js must be uninstalled before NVM can be installed, or you must allow NVM to control the existing installation. Do you want NVM to control node '+NodeVersion+'?', mbConfirmation, MB_YESNO) = IDYES;
      if msg2 then begin
        TakeControl(NodePath, NodeVersion);
      end;
      if not msg2 then begin
        DeleteFile(TmpResultFile);
        WizardForm.Close;
      end;
    end;
    if not msg1 then
    begin
      TakeControl(NodePath, NodeVersion);
    end;
  end;

  // Make sure the symlink directory doesn't exist
  if DirExists(SymlinkPage.Values[0]) then begin
    // If the directory is empty, just delete it since it will be recreated anyway.
    dir1 := IsDirEmpty(SymlinkPage.Values[0]);
    if dir1 then begin
      RemoveDir(SymlinkPage.Values[0]);
    end;
    if not dir1 then begin
      msg3 := MsgBox(SymlinkPage.Values[0]+' will be overwritten and all contents will be lost. Do you want to proceed?', mbConfirmation, MB_OKCANCEL) = IDOK;
      if msg3 then begin
        RemoveDir(SymlinkPage.Values[0]);
      end;
      if not msg3 then begin
        //RaiseException('The symlink cannot be created due to a conflict with the existing directory at '+SymlinkPage.Values[0]);
        WizardForm.Close;
      end;
    end;
  end;
end;

procedure InitializeWizard;
begin
  SymlinkPage := CreateInputDirPage(wpSelectDir,
    'Set Node.js Symlink', 'The active version of Node.js will always be available here.',
    'Select the folder in which Setup should create the symlink, then click Next.',
    False, '');
  SymlinkPage.Add('This directory will automatically be added to your system path.');
  SymlinkPage.Values[0] := ExpandConstant('{pf}\nodejs');
end;

function InitializeUninstall(): Boolean;
var
  path: string;
  nvm_symlink: string;
begin
  MsgBox('Removing NVM for Windows will remove the nvm command and all versions of node.js, including global npm modules.', mbInformation, MB_OK);

  // Remove the symlink
  RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'NVM_SYMLINK', nvm_symlink);
  RemoveDir(nvm_symlink);

  // Clean the registry
  RegDeleteValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'NVM_HOME')
  RegDeleteValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'NVM_SYMLINK')
  RegDeleteValue(HKEY_CURRENT_USER,
    'Environment',
    'NVM_HOME')
  RegDeleteValue(HKEY_CURRENT_USER,
    'Environment',
    'NVM_SYMLINK')

  RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    'Path', path);

  StringChangeEx(path,'%NVM_HOME%','',True);
  StringChangeEx(path,'%NVM_SYMLINK%','',True);
  StringChangeEx(path,';;',';',True);

  RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);

  RegQueryStringValue(HKEY_CURRENT_USER,
    'Environment',
    'Path', path);

  StringChangeEx(path,'%NVM_HOME%','',True);
  StringChangeEx(path,'%NVM_SYMLINK%','',True);
  StringChangeEx(path,';;',';',True);

  RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);

  Result := True;
end;

// Generate the settings file based on user input & update registry
procedure CurStepChanged(CurStep: TSetupStep);
var
  path: string;
begin
  if CurStep = ssPostInstall then
  begin
    SaveStringToFile(ExpandConstant('{app}\settings.txt'), 'root: ' + ExpandConstant('{app}') + #13#10 + 'path: ' + SymlinkPage.Values[0] + #13#10, False);

    // Add Registry settings
    RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'NVM_HOME', ExpandConstant('{app}'));
    RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'NVM_SYMLINK', SymlinkPage.Values[0]);
    RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'NVM_HOME', ExpandConstant('{app}'));
    RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'NVM_SYMLINK', SymlinkPage.Values[0]);

    // Update system and user PATH if needed
    RegQueryStringValue(HKEY_LOCAL_MACHINE,
      'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
      'Path', path);
    if Pos('%NVM_HOME%',path) = 0 then begin
      path := path+';%NVM_HOME%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
    end;
    if Pos('%NVM_SYMLINK%',path) = 0 then begin
      path := path+';%NVM_SYMLINK%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
    end;
    RegQueryStringValue(HKEY_CURRENT_USER,
      'Environment',
      'Path', path);
    if Pos('%NVM_HOME%',path) = 0 then begin
      path := path+';%NVM_HOME%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
    end;
    if Pos('%NVM_SYMLINK%',path) = 0 then begin
      path := path+';%NVM_SYMLINK%';
      StringChangeEx(path,';;',';',True);
      RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
    end;
  end;
end;

function getSymLink(o: string): string;
begin
  Result := SymlinkPage.Values[0];
end;

function getCurrentVersion(o: string): string;
begin
  Result := nodeInUse;
end;

function isNodeAlreadyInUse(): boolean;
begin
  Result := Length(nodeInUse) > 0;
end;

[Run]
Filename: "{cmd}"; Parameters: "/C ""mklink /D ""{code:getSymLink}"" ""{code:getCurrentVersion}"""" "; Check: isNodeAlreadyInUse; Flags: runhidden;
Filename: "{cmd}"; Parameters: "/K ""set PATH={app};%PATH% && cls && nvm"""; Flags: runasoriginaluser postinstall;

[UninstallDelete]
Type: files; Name: "{app}\nvm.exe";
Type: files; Name: "{app}\elevate.cmd";
Type: files; Name: "{app}\elevate.vbs";
Type: files; Name: "{app}\nodejs.ico";
Type: files; Name: "{app}\settings.txt";
Type: filesandordirs; Name: "{app}";


updated installer

updated installer

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

#define MyAppName "C++ IFC2X3 API with bridge extensions"
#define MyAppVerName "C++ IFC2X3 API with bridge extensions 0.5.0"
#define MyAppPublisher "CSTB TIDS MOD-EVE"
#define MyAppURL "http://salle-immersive.cstb.fr"

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppVerName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\ifc2x3
DefaultGroupName=ifc2x3
OutputBaseFilename=ifc2x3-install-0.5.0-vs2005
Compression=lzma/ultra
;Compression=none
SolidCompression=false

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

[Files]
Source: ..\lib\Debug\*.dll; DestDir: {app}\bin; Flags: ignoreversion; Components: Debug
Source: ..\lib\Debug\ifc2x3d.pdb; DestDir: {app}\bin; Flags: ignoreversion; Components: Debug
Source: ..\lib\Debug\*.lib; DestDir: {app}\lib; Flags: ignoreversion; Components: Debug
Source: ..\lib\Release\*.dll; DestDir: {app}\bin; Flags: ignoreversion; Components: Release
Source: ..\lib\Release\*.lib; DestDir: {app}\lib; Flags: ignoreversion; Components: Release
Source: ..\include\*.h; DestDir: {app}\include; Flags: ignoreversion recursesubdirs createallsubdirs; Components: Release
Source: ..\src\*.cpp; DestDir: {app}\src; Flags: ignoreversion recursesubdirs createallsubdirs; Components: Debug

[Icons]
Name: {group}\Uninstall; Filename: {uninstallexe}

[Registry]
Root: HKLM; Subkey: SYSTEM\CurrentControlSet\Control\Session Manager\Environment; ValueType: string; ValueName: IFC2X3_ROOT; ValueData: {app}; afterInstall: RefreshEnvironment
Root: HKLM; Subkey: SYSTEM\CurrentControlSet\Control\Session Manager\Environment; ValueType: string; ValueName: PATH; ValueData: "{olddata};{app}\bin"; afterInstall: RefreshEnvironment

[Code]
function SendMessageTimeout(hwnd, msg, wParam: LongInt; lParam: String; fuFlags, uTimeout, lpdwResult: LongInt): LongInt;
external 'SendMessageTimeoutA@user32.dll stdcall';

const
HWND_BROADCASTS = 65535;
SMTO_ABORTIFHUNG = 2;
WM_SETTINGCHANGE = 26;

procedure RefreshEnvironment();
begin
SendMessageTimeout(HWND_BROADCASTS, WM_SETTINGCHANGE, 0, 'Environment', SMTO_ABORTIFHUNG, 5000, 0);
end;
[Components]
Name: Release; Description: Optimized binary version of the API; Types: custom full compact; Languages: ; Flags: fixed
Name: Debug; Description: Debug binary version of the API; Types: custom full

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

#define MyAppName "C++ IFC2X3 API"
#define MyAppVerName "C++ IFC2X3 API 0.3.0"
#define MyAppPublisher "CSTB TIDS MOD-EVE by Geoffrey Arthaud"
#define MyAppURL "http://salle-immersive.cstb.fr"

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppVerName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\ifc2x3
DefaultGroupName=ifc2x3
OutputBaseFilename=ifc2x3-install-0.3.0-vs2005
Compression=lzma/ultra
;Compression=none
SolidCompression=false

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

[Files]
Source: ..\lib\Debug\*.dll; DestDir: {app}\bin; Flags: ignoreversion; Components: Debug
Source: ..\lib\Debug\ifc2x3.pdb; DestDir: {app}\bin; Flags: ignoreversion; Components: Debug
Source: ..\lib\Debug\*.lib; DestDir: {app}\lib; Flags: ignoreversion; Components: Debug
Source: ..\lib\Release\*.dll; DestDir: {app}\bin; Flags: ignoreversion; Components: Release
Source: ..\lib\Release\*.lib; DestDir: {app}\lib; Flags: ignoreversion; Components: Release
Source: ..\include\*.h; DestDir: {app}\include; Flags: ignoreversion recursesubdirs createallsubdirs; Components: Release
Source: ..\src\*.cpp; DestDir: {app}\src; Flags: ignoreversion recursesubdirs createallsubdirs; Components: Debug

[Icons]
Name: {group}\Uninstall; Filename: {uninstallexe}

[Registry]
Root: HKLM; Subkey: SYSTEM\CurrentControlSet\Control\Session Manager\Environment; ValueType: string; ValueName: IFC2X3_ROOT; ValueData: {app}; afterInstall: RefreshEnvironment
Root: HKLM; Subkey: SYSTEM\CurrentControlSet\Control\Session Manager\Environment; ValueType: string; ValueName: PATH; ValueData: "{olddata};{app}\bin"; afterInstall: RefreshEnvironment

[Code]
function SendMessageTimeout(hwnd, msg, wParam: LongInt; lParam: String; fuFlags, uTimeout, lpdwResult: LongInt): LongInt;
external 'SendMessageTimeoutA@user32.dll stdcall';

const
HWND_BROADCASTS = 65535;
SMTO_ABORTIFHUNG = 2;
WM_SETTINGCHANGE = 26;

procedure RefreshEnvironment();
begin
SendMessageTimeout(HWND_BROADCASTS, WM_SETTINGCHANGE, 0, 'Environment', SMTO_ABORTIFHUNG, 5000, 0);
end;
[Components]
Name: Release; Description: Optimized binary version of the API; Types: custom full compact; Languages: ; Flags: fixed
Name: Debug; Description: Debug binary version of the API; Types: custom full