installer: uninstall the official Notepad2 installer when installing

TODO: simplify it

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

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

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

; $Id$

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

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

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

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

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

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

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

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

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

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

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

#expr ParseVersion(bindir + "\Release_x86\Notepad2.exe", VerMajor, VerMinor, VerBuild, VerRevision)
#define app_version  str(VerMajor) + "." + str(VerMinor) + "." + str(VerBuild) + "." + str(VerRevision)
#define app_name     "Notepad2-mod"
#define quick_launch "{userappdata}\Microsoft\Internet Explorer\Quick Launch"
#define IFEO         "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe"

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

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

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

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

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

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

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

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

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

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

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

[Code]
// Global variables/constants and general functions
const installer_mutex_name = '{#app_name}' + '_setup_mutex';

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

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

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

////////////////////////////////////////
//  Custom functions and procedures   //
////////////////////////////////////////

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

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

#elif defined(sse2_required)

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

#endif

function IsOldBuildInstalled(): Boolean;
begin
  if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad2') and
  FileExists(ExpandConstant('{pf}\Notepad2\Uninstall.inf')) then begin
    Log('Custom Code: The old build is installed');
    Result := True;
  end
  else begin
    Log('Custom Code: The old build is NOT installed');
    Result := False;
  end;
end;

function IsOfficialBuildInstalled(): Boolean;
begin
  if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad2') and
  FileExists(ExpandConstant('{pf}\Notepad2\Notepad2.inf')) then begin
    Log('Custom Code: The official Notepad2 build is installed');
    Result := True;
  end
  else begin
    Log('Custom Code: The official Notepad2 build is NOT installed');
    Result := False;
  end;
end;

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

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

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

  // default return value
  Log('Custom Code: Will try to uninstall the old build');
  Result := 0;
    if Exec('rundll32.exe', ExpandConstant('advpack.dll,LaunchINFSectionEx "{pf}\Notepad2\Uninstall.inf",DefaultUninstall,,8,N'), '', SW_HIDE, ewWaitUntilTerminated, iResultCode) then begin
      Result := 2;
      Sleep(200);
      Log('Custom Code: The old build was successfully uninstalled');
    end
    else begin
      Result := 1;
      Log('Custom Code: Something went wrong when uninstalling the old build');
    end;
end;

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

  // default return value
  Log('Custom Code: Will try to uninstall the old build');
  Result := 0;
    if Exec('rundll32.exe', ExpandConstant('advpack.dll,LaunchINFSectionEx "{pf}\Notepad2\Notepad2.inf",DefaultUninstall,,8,N'), '', SW_HIDE, ewWaitUntilTerminated, iResultCode) then begin
      Result := 2;
      Sleep(200);
      Log('Custom Code: The official Notepad2 build was successfully uninstalled');
    end
    else begin
      Result := 1;
      Log('Custom Code: Something went wrong when uninstalling the official Notepad2 build');
    end;
end;

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

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

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

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

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

procedure CurStepChanged(CurStep: TSetupStep);
begin

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

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

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

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

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

end;

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

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

  end;
end;

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

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

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

    if iMsgBoxResult = IDCANCEL then
      Result := False;

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

  end;
end;

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

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

    if iMsgBoxResult = IDCANCEL then
      Result := False;

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

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

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

; $Id$

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

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

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

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

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

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

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

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

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

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

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

#expr ParseVersion(bindir + "\Release_x86\Notepad2.exe", VerMajor, VerMinor, VerBuild, VerRevision)
#define app_version  str(VerMajor) + "." + str(VerMinor) + "." + str(VerBuild) + "." + str(VerRevision)
#define app_name     "Notepad2-mod"
#define quick_launch "{userappdata}\Microsoft\Internet Explorer\Quick Launch"
#define IFEO         "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe"

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

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

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

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

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

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

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

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

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

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

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

[Code]
// Global variables/constants and general functions
const installer_mutex_name = '{#app_name}' + '_setup_mutex';

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

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

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

////////////////////////////////////////
//  Custom functions and procedures   //
////////////////////////////////////////

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

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

#elif defined(sse2_required)

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

#endif

function IsOldBuildInstalled(): Boolean;
begin
  if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad2') and
  FileExists(ExpandConstant('{pf}\Notepad2\Uninstall.inf')) then begin
    Log('Custom Code: The old build is installed');
    Result := True;
  end
  else begin
    Log('Custom Code: The old build is NOT installed');
    Result := False;
  end;
end;

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

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

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

  // default return value
  Log('Custom Code: Will try to uninstall the old build');
  Result := 0;
    if Exec('rundll32.exe', ExpandConstant('advpack.dll,LaunchINFSectionEx "{pf}\Notepad2\Uninstall.inf",DefaultUninstall,,8,N'), '', SW_HIDE, ewWaitUntilTerminated, iResultCode) then begin
      Result := 2;
      Sleep(200);
      Log('Custom Code: The old build was successfully uninstalled');
    end
    else begin
      Result := 1;
      Log('Custom Code: Something went wrong when uninstalling the old build');
    end;
end;

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

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

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

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

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

procedure CurStepChanged(CurStep: TSetupStep);
begin

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

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

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

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

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

end;

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

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

  end;
end;

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

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

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

    if iMsgBoxResult = IDCANCEL then
      Result := False;

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

  end;
end;

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

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

    if iMsgBoxResult = IDCANCEL then
      Result := False;

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


added installation types such as [full,server,client,custom]

[Setup]
AppName=UniMRCP
AppVerName=UniMRCP-0.2.0
AppPublisher=UniMRCP
AppPublisherURL=http://www.unimrcp.org/
AppSupportURL=http://groups.google.com/group/unimrcp
AppUpdatesURL=http://code.google.com/p/unimrcp/downloads/list
DefaultDirName={pf}\UniMRCP
DefaultGroupName=UniMRCP
OutputBaseFilename=unimrcp-0.2.0
Compression=lzma
InternalCompressLevel=max
SolidCompression=true

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

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

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

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


Fixes call to runvistrails.py

Fixes call to runvistrails.py

[Dirs]
Name: {app}\vistrails
Name: {app}\examples; Components: examples; Tasks:
Name: {app}\extensions; Components: extensions; Tasks:
Name: {app}\doc; Components: usersguide; Tasks:
Name: {app}\scripts
Name: {app}\scripts\gen_vtk_examples
Name: {app}\libsrc
Name: {app}\{#python}
Name: {app}\{#python}\DLLs
Name: {app}\{#python}\include
Name: {app}\{#python}\Lib
Name: {app}\{#python}\libs
Name: {app}\{#python}\Scripts
Name: {app}\{#python}\sip
Name: {app}\{#python}\tcl
Name: {app}\{#python}\Tools
[Components]
Name: main; Description: Main Files; Types: full compact custom; Flags: fixed
Name: examples; Description: Example Files; Types: full
Name: extensions; Description: Extension Files; Types: full
Name: usersguide; Description: User's Guide PDF document; Types: full

[Icons]
Name: {group}\VisTrails; Filename: {app}\{#python}\python.exe; WorkingDir: {app}; IconFilename: {app}\vistrails\gui\resources\images\vistrails_icon_small.ico; IconIndex: 0; Components: ; Parameters: vistrails\run.py
Name: {commondesktop}\VisTrails; Filename: {app}\{#python}\python.exe; WorkingDir: {app}; IconFilename: {app}\vistrails\gui\resources\images\vistrails_icon_small.ico; IconIndex: 0; Parameters: """runvistrails.py"" ""{#python}\python.exe"" ""vistrails\run.py"" ""{app}"""; Components: main; Tasks: desktopicon
Name: {group}\Uninstall VisTrails; Filename: {uninstallexe}
Name: {group}\VisTrails.pdf; Filename: {app}\doc\VisTrails.pdf; Components: usersguide
[Tasks]
Name: desktopicon; Description: Create a &desktop icon; GroupDescription: Additional icons:; Components: main
Name: desktopicon\common; Description: For all users; GroupDescription: Additional icons:; Components: main; Flags: exclusive
Name: desktopicon\user; Description: For the current user only; GroupDescription: Additional icons:; Components: main; Flags: exclusive unchecked
Name: quicklaunchicon; Description: Create a &Quick Launch icon; GroupDescription: Additional icons:; Components: main; Flags: unchecked
Name: associatefiles; Description: Associate *.vt files with VisTrails; GroupDescription: File Association:; Components: main
[_ISTool]
LogFile=Output\build.log
LogFileAppend=false
[Registry]
Root: HKCR; Subkey: .vt; ValueType: string; ValueData: VisTrailsFile; Flags: uninsdeletevalue; Tasks: associatefiles
Root: HKCR; Subkey: VisTrailsFile; ValueType: string; ValueData: VisTrails File; Flags: uninsdeletekey; Tasks: associatefiles
Root: HKCR; Subkey: VisTrailsFile\DefaultIcon; ValueType: string; ValueData: {app}\vistrails\gui\resources\images\vistrails_icon_small.ico; Tasks: associatefiles; Flags: uninsdeletekey
Root: HKCR; Subkey: VisTrailsFile\shell\open\command; ValueType: string; ValueData: """{app}\{#python}\python.exe"" ""{app}\runvistrails.py"" ""{app}\{#python}\python.exe"" ""{app}\vistrails\run.py"" ""{app}"" ""%1"""; Tasks: associatefiles; Flags: uninsdeletekey
Root: HKCR; Subkey: .vtl; ValueType: string; ValueData: VisTrailsFile; Flags: uninsdeletevalue; Tasks: associatefiles
[InstallDelete]
Name: {app}\dot.exe; Type: files
Name: {app}\freetype6.dll; Type: files
Name: {app}\jpeg.dll; Type: files
Name: {app}\libexpat.dll; Type: files
Name: {app}\libexpatw.dll; Type: files
Name: {app}\png.dll; Type: files
Name: {app}\z.dll; Type: files
Name: {app}\zlib1.dll; Type: files
Name: {app}\{#python}; Type: filesandordirs
Name: {app}\*.pyd; Type: files
Name: {app}\dgnlib.dll; Type: files
Name: {app}\_Xdmf.dll; Type: files
Name: {app}\geotiff.dll; Type: files
Name: {app}\libmysql.dll; Type: files
Name: {app}\vistrails; Type: filesandordirs
Name: {app}\vistrails\packages\gridfield; Type: filesandordirs
Name: {app}\lib\site-packages; Type: filesandordirs
[Run]
Filename: {tmp}\vcredist_{#bits}.exe; Parameters: /Q; Components: ; Tasks:

[ThirdPartySettings]
CompileLogFile=Output\build.log
CompileLogMethod=append

[PreCompile]
Name: "C:\{#python_src}\python.exe"; Parameters: "C:\Users\vistrails\code\vistrails\scripts\dist\windows\Input\download_usersguide.py"; Flags: abortonerror cmdprompt

[PreCompile]
Name: "C:\{#python_src}\python.exe"; Parameters: "-m compileall C:\Users\vistrails\code"; Flags: abortonerror cmdprompt

[Code]
var
  FinishedInstall: Boolean;
function CustomAppDir(Param: String): String;
begin
  if IsAdminLoggedOn then
    Result := ExpandConstant('{pf}')
  else
    Result := ExpandConstant('{userappdata}')
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
    FinishedInstall := True;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
end;

procedure DeleteVCRedistRuntimeTemporaryFiles();
var
   i : Integer;
   byCounter : Byte;
   byDrive : Byte;
   strFile1, strFile2, strFile3 : String;
   strRootDrivePath : String;
   //totally there are 24 files to be deleted
   arrFiles : Array [1..24] Of String;
begin

   //We will check the following root drives
   //C, D, E, F, G, H, I, J, K, L, M
   For byCounter := 67 to 77 do
   Begin
      strRootDrivePath := Chr(byCounter) + ':\';
      arrFiles[1] := strRootDrivePath + 'vcredist.bmp';
      arrFiles[2] := strRootDrivePath + 'VC_RED.cab';
      arrFiles[3] := strRootDrivePath + 'VC_RED.MSI';

      //If these 3 files then we have found the right
      //drive in which the VC runtime files are extracted
      If (FileExists(arrFiles[1]) And
          FileExists(arrFiles[2]) And
          FileExists(arrFiles[3])) Then
      Begin

          arrFiles[4] := strRootDrivePath + 'eula.1028.txt';
          arrFiles[5] := strRootDrivePath + 'eula.1031.txt';
          arrFiles[6] := strRootDrivePath + 'eula.1033.txt';
          arrFiles[7] := strRootDrivePath + 'eula.1036.txt';
          arrFiles[8] := strRootDrivePath + 'eula.1040.txt';
          arrFiles[9] := strRootDrivePath + 'eula.1041.txt';
          arrFiles[10] := strRootDrivePath + 'eula.1042.txt';
          arrFiles[11] := strRootDrivePath + 'eula.2052.txt';
          arrFiles[12] := strRootDrivePath + 'eula.3082.txt';
          arrFiles[13] := strRootDrivePath + 'globdata.ini';
          arrFiles[14] := strRootDrivePath + 'install.exe';
          arrFiles[15] := strRootDrivePath + 'install.ini';
          arrFiles[16] := strRootDrivePath + 'install.res.1028.dll';
          arrFiles[17] := strRootDrivePath + 'install.res.1031.dll';
          arrFiles[18] := strRootDrivePath + 'install.res.1033.dll';
          arrFiles[19] := strRootDrivePath + 'install.res.1036.dll';
          arrFiles[20] := strRootDrivePath + 'install.res.1040.dll';
          arrFiles[21] := strRootDrivePath + 'install.res.1041.dll';
          arrFiles[22] := strRootDrivePath + 'install.res.1042.dll';
          arrFiles[23] := strRootDrivePath + 'install.res.2052.dll';
          arrFiles[24] := strRootDrivePath + 'install.res.3082.dll';

          For i := 1 to 24 Do
          Begin
            DeleteFile(arrFiles[i]);
          End;

          //Now that we have found and deleted all the files
          //we will break
          Break;
      End;
   End;
End;

procedure DeinitializeSetup();
var
  qvtk: String;
begin
  if FinishedInstall then begin
      qvtk := ExpandConstant('{app}') + '\vistrails\packages\spreadsheet\widgets\QVTKWidget';
    if DirExists(qvtk) then
    DelTree(qvtk, True, True, True);
  end;
  DeleteVCRedistRuntimeTemporaryFiles();
end;

[InnoIDE_Settings]
LogFile=Output\build.log
LogFileOverwrite=false

[Dirs]
Name: {app}\vistrails
Name: {app}\examples; Components: examples; Tasks:
Name: {app}\extensions; Components: extensions; Tasks:
Name: {app}\doc; Components: usersguide; Tasks:
Name: {app}\scripts
Name: {app}\scripts\gen_vtk_examples
Name: {app}\libsrc
Name: {app}\{#python}
Name: {app}\{#python}\DLLs
Name: {app}\{#python}\include
Name: {app}\{#python}\Lib
Name: {app}\{#python}\libs
Name: {app}\{#python}\Scripts
Name: {app}\{#python}\sip
Name: {app}\{#python}\tcl
Name: {app}\{#python}\Tools
[Components]
Name: main; Description: Main Files; Types: full compact custom; Flags: fixed
Name: examples; Description: Example Files; Types: full
Name: extensions; Description: Extension Files; Types: full
Name: usersguide; Description: User's Guide PDF document; Types: full

[Icons]
Name: {group}\VisTrails; Filename: {app}\{#python}\python.exe; WorkingDir: {app}; IconFilename: {app}\vistrails\gui\resources\images\vistrails_icon_small.ico; IconIndex: 0; Components: ; Parameters: vistrails\run.py
Name: {commondesktop}\VisTrails; Filename: {app}\{#python}\python.exe; WorkingDir: {app}; IconFilename: {app}\vistrails\gui\resources\images\vistrails_icon_small.ico; IconIndex: 0; Parameters: """{app}\{#python}\python.exe"" ""runvistrails.py"" ""{#python}\python.exe"" ""vistrails\run.py"" ""{app}"""; Components: main; Tasks: desktopicon
Name: {group}\Uninstall VisTrails; Filename: {uninstallexe}
Name: {group}\VisTrails.pdf; Filename: {app}\doc\VisTrails.pdf; Components: usersguide
[Tasks]
Name: desktopicon; Description: Create a &desktop icon; GroupDescription: Additional icons:; Components: main
Name: desktopicon\common; Description: For all users; GroupDescription: Additional icons:; Components: main; Flags: exclusive
Name: desktopicon\user; Description: For the current user only; GroupDescription: Additional icons:; Components: main; Flags: exclusive unchecked
Name: quicklaunchicon; Description: Create a &Quick Launch icon; GroupDescription: Additional icons:; Components: main; Flags: unchecked
Name: associatefiles; Description: Associate *.vt files with VisTrails; GroupDescription: File Association:; Components: main
[_ISTool]
LogFile=Output\build.log
LogFileAppend=false
[Registry]
Root: HKCR; Subkey: .vt; ValueType: string; ValueData: VisTrailsFile; Flags: uninsdeletevalue; Tasks: associatefiles
Root: HKCR; Subkey: VisTrailsFile; ValueType: string; ValueData: VisTrails File; Flags: uninsdeletekey; Tasks: associatefiles
Root: HKCR; Subkey: VisTrailsFile\DefaultIcon; ValueType: string; ValueData: {app}\vistrails\gui\resources\images\vistrails_icon_small.ico; Tasks: associatefiles; Flags: uninsdeletekey
Root: HKCR; Subkey: VisTrailsFile\shell\open\command; ValueType: string; ValueData: """{app}\{#python}\python.exe"" ""{app}\runvistrails.py"" ""{app}\{#python}\python.exe"" ""{app}\vistrails\run.py"" ""{app}"" ""%1"""; Tasks: associatefiles; Flags: uninsdeletekey
Root: HKCR; Subkey: .vtl; ValueType: string; ValueData: VisTrailsFile; Flags: uninsdeletevalue; Tasks: associatefiles
[InstallDelete]
Name: {app}\dot.exe; Type: files
Name: {app}\freetype6.dll; Type: files
Name: {app}\jpeg.dll; Type: files
Name: {app}\libexpat.dll; Type: files
Name: {app}\libexpatw.dll; Type: files
Name: {app}\png.dll; Type: files
Name: {app}\z.dll; Type: files
Name: {app}\zlib1.dll; Type: files
Name: {app}\{#python}; Type: filesandordirs
Name: {app}\*.pyd; Type: files
Name: {app}\dgnlib.dll; Type: files
Name: {app}\_Xdmf.dll; Type: files
Name: {app}\geotiff.dll; Type: files
Name: {app}\libmysql.dll; Type: files
Name: {app}\vistrails; Type: filesandordirs
Name: {app}\vistrails\packages\gridfield; Type: filesandordirs
Name: {app}\lib\site-packages; Type: filesandordirs
[Run]
Filename: {tmp}\vcredist_{#bits}.exe; Parameters: /Q; Components: ; Tasks:

[ThirdPartySettings]
CompileLogFile=Output\build.log
CompileLogMethod=append

[PreCompile]
Name: "C:\{#python_src}\python.exe"; Parameters: "C:\Users\vistrails\code\vistrails\scripts\dist\windows\Input\download_usersguide.py"; Flags: abortonerror cmdprompt

[PreCompile]
Name: "C:\{#python_src}\python.exe"; Parameters: "-m compileall C:\Users\vistrails\code"; Flags: abortonerror cmdprompt

[Code]
var
  FinishedInstall: Boolean;
function CustomAppDir(Param: String): String;
begin
  if IsAdminLoggedOn then
    Result := ExpandConstant('{pf}')
  else
    Result := ExpandConstant('{userappdata}')
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
    FinishedInstall := True;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
end;

procedure DeleteVCRedistRuntimeTemporaryFiles();
var
   i : Integer;
   byCounter : Byte;
   byDrive : Byte;
   strFile1, strFile2, strFile3 : String;
   strRootDrivePath : String;
   //totally there are 24 files to be deleted
   arrFiles : Array [1..24] Of String;
begin

   //We will check the following root drives
   //C, D, E, F, G, H, I, J, K, L, M
   For byCounter := 67 to 77 do
   Begin
      strRootDrivePath := Chr(byCounter) + ':\';
      arrFiles[1] := strRootDrivePath + 'vcredist.bmp';
      arrFiles[2] := strRootDrivePath + 'VC_RED.cab';
      arrFiles[3] := strRootDrivePath + 'VC_RED.MSI';

      //If these 3 files then we have found the right
      //drive in which the VC runtime files are extracted
      If (FileExists(arrFiles[1]) And
          FileExists(arrFiles[2]) And
          FileExists(arrFiles[3])) Then
      Begin

          arrFiles[4] := strRootDrivePath + 'eula.1028.txt';
          arrFiles[5] := strRootDrivePath + 'eula.1031.txt';
          arrFiles[6] := strRootDrivePath + 'eula.1033.txt';
          arrFiles[7] := strRootDrivePath + 'eula.1036.txt';
          arrFiles[8] := strRootDrivePath + 'eula.1040.txt';
          arrFiles[9] := strRootDrivePath + 'eula.1041.txt';
          arrFiles[10] := strRootDrivePath + 'eula.1042.txt';
          arrFiles[11] := strRootDrivePath + 'eula.2052.txt';
          arrFiles[12] := strRootDrivePath + 'eula.3082.txt';
          arrFiles[13] := strRootDrivePath + 'globdata.ini';
          arrFiles[14] := strRootDrivePath + 'install.exe';
          arrFiles[15] := strRootDrivePath + 'install.ini';
          arrFiles[16] := strRootDrivePath + 'install.res.1028.dll';
          arrFiles[17] := strRootDrivePath + 'install.res.1031.dll';
          arrFiles[18] := strRootDrivePath + 'install.res.1033.dll';
          arrFiles[19] := strRootDrivePath + 'install.res.1036.dll';
          arrFiles[20] := strRootDrivePath + 'install.res.1040.dll';
          arrFiles[21] := strRootDrivePath + 'install.res.1041.dll';
          arrFiles[22] := strRootDrivePath + 'install.res.1042.dll';
          arrFiles[23] := strRootDrivePath + 'install.res.2052.dll';
          arrFiles[24] := strRootDrivePath + 'install.res.3082.dll';

          For i := 1 to 24 Do
          Begin
            DeleteFile(arrFiles[i]);
          End;

          //Now that we have found and deleted all the files
          //we will break
          Break;
      End;
   End;
End;

procedure DeinitializeSetup();
var
  qvtk: String;
begin
  if FinishedInstall then begin
      qvtk := ExpandConstant('{app}') + '\vistrails\packages\spreadsheet\widgets\QVTKWidget';
    if DirExists(qvtk) then
    DelTree(qvtk, True, True, True);
  end;
  DeleteVCRedistRuntimeTemporaryFiles();
end;

[InnoIDE_Settings]
LogFile=Output\build.log
LogFileOverwrite=false


Check for Windows compatible versions (2000 and XP).

git-svn-id: 4c7b768bc2e2a56aa1c56b1b5a9454ba68342430@2815 ac9c905b-388a-4ddf-9b6a-4063a022bc57

; Script generated by the Inno Setup Script Wizard.

#define MyAppName "Logtalk"
#define MyAppVerName "Logtalk 2.28.0"
#define MyAppPublisher "Paulo Moura"
#define MyAppURL "http://logtalk.org"
#define MyAppUrlName "Logtalk Web Site.url"

#define LOGTALKHOME "{reg:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment,LOGTALKHOME|{pf}\Logtalk}"
#define LOGTALKUSER "{reg:HKCU\Environment,LOGTALKUSER|{userdocs}\logtalk}"

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppVerName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ChangesEnvironment=yes
DefaultDirName={#LOGTALKHOME}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
LicenseFile=C:\logtalk\LICENSE
InfoBeforeFile=C:\logtalk\README
OutputBaseFilename=lgt2280
Compression=lzma
SolidCompression=yes

VersionInfoVersion=2.28.0
VersionInfoCopyright= Paulo Moura, 1998-2006

AllowRootDirectory=yes

MinVersion=0,5.0

[Types]
Name: "full"; Description: "Full installation (recommended)"
Name: "base"; Description: "Base system installation"
Name: "user"; Description: "User-modifiable files installation (must be run by all end-users)"
Name: "prolog"; Description: "Prolog integration (see documentation for compatibility details)"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "base"; Description: "Base system"; Types: full base custom
Name: "user"; Description: "User-modifiable files"; Types: full user custom; Flags: checkablealone
Name: "user\backup"; Description: "Backup current user-modifiable files"; Types: full user custom
Name: "prolog"; Description: "Prolog integration"; Types: full prolog custom
Name: "prolog\ciao"; Description: "Ciao Prolog integration"; Types: full prolog custom
Name: "prolog\eclipse"; Description: "ECLiPSe integration"; Types: full prolog custom
Name: "prolog\gprolog"; Description: "GNU Prolog integration"; Types: full prolog custom
Name: "prolog\plc"; Description: "K-Prolog integration"; Types: full prolog custom
Name: "prolog\sicstus"; Description: "SICStus Prolog integration"; Types: full prolog custom
Name: "prolog\swi"; Description: "SWI-Prolog integration"; Types: full prolog custom
Name: "prolog\xsb"; Description: "XSB integration"; Types: full prolog custom
Name: "prolog\yap"; Description: "YAP integration"; Types: full prolog custom

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

[Messages]
BeveledLabel=      Logtalk 2.28.0  Paulo Moura, 1998-2006

[Files]
Source: "C:\logtalk\compiler\*"; Excludes: "CVS"; DestDir: "{app}\compiler"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\configs\*"; Excludes: "CVS"; DestDir: "{app}\configs"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\contributions\*"; Excludes: "CVS"; DestDir: "{app}\contributions"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\examples\*"; Excludes: "CVS"; DestDir: "{app}\examples"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\libpaths\*"; Excludes: "CVS"; DestDir: "{app}\libpaths"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\library\*"; Excludes: "CVS"; DestDir: "{app}\library"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\manuals\*"; Excludes: "CVS"; DestDir: "{app}\manuals"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\scripts\*"; Excludes: "CVS"; DestDir: "{app}\scripts"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\wenv\*"; Excludes: "CVS"; DestDir: "{app}\wenv"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\xml\*"; Excludes: "CVS"; DestDir: "{app}\xml"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\BIBLIOGRAPHY"; DestDir: "{app}"; DestName: "BIBLIOGRAPHY.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\INSTALL"; DestDir: "{app}"; DestName: "INSTALL.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\LICENSE"; DestDir: "{app}"; DestName: "LICENSE.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\QUICK_START"; DestDir: "{app}"; DestName: "QUICK_START.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\README"; DestDir: "{app}"; DestName: "README.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\RELEASE_NOTES"; DestDir: "{app}"; DestName: "RELEASE_NOTES.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\UPGRADING"; DestDir: "{app}"; DestName: "UPGRADING.txt"; Components: base; Flags: ignoreversion

Source: "{#LOGTALKUSER}\*"; DestDir: "{#LOGTALKUSER} backup"; Components: user\backup; Flags: external recursesubdirs createallsubdirs skipifsourcedoesntexist uninsneveruninstall

Source: "C:\logtalk\configs\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\configs"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\contributions\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\contributions"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\examples\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\examples"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\libpaths\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\libpaths"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\library\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\library"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\xml\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\xml"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall

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

[Icons]
Name: "{group}\{#MyAppName} Bibliography"; Filename: "{app}\BIBLIOGRAPHY.txt"; Components: base
Name: "{group}\{#MyAppName} Documentation"; Filename: "{app}\manuals\index.html"; Components: base
Name: "{group}\{#MyAppName} License"; Filename: "{app}\LICENSE.txt"; Components: base
Name: "{group}\{#MyAppName} Release Notes"; Filename: "{app}\RELEASE_NOTES.txt"; Components: base
Name: "{group}\{#MyAppName} Read Me"; Filename: "{app}\README.txt"; Components: base

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

Name: "{#LOGTALKUSER}\manuals"; Filename: "{app}\manuals"; Components: user
Name: "{#LOGTALKUSER}\wenv"; Filename: "{app}\wenv"; Components: user

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "LOGTALKHOME"; ValueData: "{app}"; Flags: deletevalue uninsdeletevalue
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKUSER"; ValueData: "{#LOGTALKUSER}"; Flags: createvalueifdoesntexist

[Run]
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_ciaolgt.js"""; Description: "Ciao Prolog integration"; Components: prolog\ciao
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_eclipselgt.js"""; Description: "ECLiPSe integration"; Components: prolog\eclipse
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_gplgt.js"""; Description: "GNU Prolog integration"; Components: prolog\gprolog
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_plclgt.js"""; Description: "K-Prolog integration"; Components: prolog\plc
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_sicstuslgt.js"""; Description: "SICStus Prolog integration"; Components: prolog\sicstus
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_swilgt.js"""; Description: "SWI-Prolog integration"; Components: prolog\swi
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_xsblgt.js"""; Description: "XSB integration"; Components: prolog\xsb
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_yaplgt.js"""; Description: "YAP integration"; Components: prolog\yap

Filename: "{app}\RELEASE_NOTES.txt"; Description: "View the release notes"; Flags: postinstall shellexec skipifsilent
Filename: "{app}\INSTALL.txt"; Description: "Review the install instructions for completing your setup"; Flags: postinstall shellexec skipifsilent

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

; Script generated by the Inno Setup Script Wizard.

#define MyAppName "Logtalk"
#define MyAppVerName "Logtalk 2.28.0"
#define MyAppPublisher "Paulo Moura"
#define MyAppURL "http://logtalk.org"
#define MyAppUrlName "Logtalk Web Site.url"

#define LOGTALKHOME "{reg:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment,LOGTALKHOME|{pf}\Logtalk}"
#define LOGTALKUSER "{reg:HKCU\Environment,LOGTALKUSER|{userdocs}\logtalk}"

[Setup]
AppName={#MyAppName}
AppVerName={#MyAppVerName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ChangesEnvironment=yes
DefaultDirName={#LOGTALKHOME}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
LicenseFile=C:\logtalk\LICENSE
InfoBeforeFile=C:\logtalk\README
OutputBaseFilename=lgt2280
Compression=lzma
SolidCompression=yes

VersionInfoVersion=2.28.0
VersionInfoCopyright= Paulo Moura, 1998-2006

AllowRootDirectory=yes

MinVersion=5.0,5.0

[Types]
Name: "full"; Description: "Full installation (recommended)"
Name: "base"; Description: "Base system installation"
Name: "user"; Description: "User-modifiable files installation (must be run by all end-users)"
Name: "prolog"; Description: "Prolog integration (see documentation for compatibility details)"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "base"; Description: "Base system"; Types: full base custom
Name: "user"; Description: "User-modifiable files"; Types: full user custom; Flags: checkablealone
Name: "user\backup"; Description: "Backup current user-modifiable files"; Types: full user custom
Name: "prolog"; Description: "Prolog integration"; Types: full prolog custom
Name: "prolog\ciao"; Description: "Ciao Prolog integration"; Types: full prolog custom
Name: "prolog\eclipse"; Description: "ECLiPSe integration"; Types: full prolog custom
Name: "prolog\gprolog"; Description: "GNU Prolog integration"; Types: full prolog custom
Name: "prolog\plc"; Description: "K-Prolog integration"; Types: full prolog custom
Name: "prolog\sicstus"; Description: "SICStus Prolog integration"; Types: full prolog custom
Name: "prolog\swi"; Description: "SWI-Prolog integration"; Types: full prolog custom
Name: "prolog\xsb"; Description: "XSB integration"; Types: full prolog custom
Name: "prolog\yap"; Description: "YAP integration"; Types: full prolog custom

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

[Messages]
BeveledLabel=      Logtalk 2.28.0  Paulo Moura, 1998-2006

[Files]
Source: "C:\logtalk\compiler\*"; Excludes: "CVS"; DestDir: "{app}\compiler"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\configs\*"; Excludes: "CVS"; DestDir: "{app}\configs"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\contributions\*"; Excludes: "CVS"; DestDir: "{app}\contributions"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\examples\*"; Excludes: "CVS"; DestDir: "{app}\examples"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\libpaths\*"; Excludes: "CVS"; DestDir: "{app}\libpaths"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\library\*"; Excludes: "CVS"; DestDir: "{app}\library"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\manuals\*"; Excludes: "CVS"; DestDir: "{app}\manuals"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\scripts\*"; Excludes: "CVS"; DestDir: "{app}\scripts"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\wenv\*"; Excludes: "CVS"; DestDir: "{app}\wenv"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\xml\*"; Excludes: "CVS"; DestDir: "{app}\xml"; Components: base; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\logtalk\BIBLIOGRAPHY"; DestDir: "{app}"; DestName: "BIBLIOGRAPHY.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\INSTALL"; DestDir: "{app}"; DestName: "INSTALL.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\LICENSE"; DestDir: "{app}"; DestName: "LICENSE.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\QUICK_START"; DestDir: "{app}"; DestName: "QUICK_START.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\README"; DestDir: "{app}"; DestName: "README.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\RELEASE_NOTES"; DestDir: "{app}"; DestName: "RELEASE_NOTES.txt"; Components: base; Flags: ignoreversion
Source: "C:\logtalk\UPGRADING"; DestDir: "{app}"; DestName: "UPGRADING.txt"; Components: base; Flags: ignoreversion

Source: "{#LOGTALKUSER}\*"; DestDir: "{#LOGTALKUSER} backup"; Components: user\backup; Flags: external recursesubdirs createallsubdirs skipifsourcedoesntexist uninsneveruninstall

Source: "C:\logtalk\configs\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\configs"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\contributions\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\contributions"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\examples\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\examples"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\libpaths\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\libpaths"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\library\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\library"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall
Source: "C:\logtalk\xml\*"; Excludes: "CVS"; DestDir: "{#LOGTALKUSER}\xml"; Components: user; Flags: ignoreversion recursesubdirs createallsubdirs uninsneveruninstall

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

[Icons]
Name: "{group}\{#MyAppName} Bibliography"; Filename: "{app}\BIBLIOGRAPHY.txt"; Components: base
Name: "{group}\{#MyAppName} Documentation"; Filename: "{app}\manuals\index.html"; Components: base
Name: "{group}\{#MyAppName} License"; Filename: "{app}\LICENSE.txt"; Components: base
Name: "{group}\{#MyAppName} Release Notes"; Filename: "{app}\RELEASE_NOTES.txt"; Components: base
Name: "{group}\{#MyAppName} Read Me"; Filename: "{app}\README.txt"; Components: base

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

Name: "{#LOGTALKUSER}\manuals"; Filename: "{app}\manuals"; Components: user
Name: "{#LOGTALKUSER}\wenv"; Filename: "{app}\wenv"; Components: user

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "LOGTALKHOME"; ValueData: "{app}"; Flags: deletevalue uninsdeletevalue
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "LOGTALKUSER"; ValueData: "{#LOGTALKUSER}"; Flags: createvalueifdoesntexist

[Run]
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_ciaolgt.js"""; Description: "Ciao Prolog integration"; Components: prolog\ciao
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_eclipselgt.js"""; Description: "ECLiPSe integration"; Components: prolog\eclipse
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_gplgt.js"""; Description: "GNU Prolog integration"; Components: prolog\gprolog
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_plclgt.js"""; Description: "K-Prolog integration"; Components: prolog\plc
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_sicstuslgt.js"""; Description: "SICStus Prolog integration"; Components: prolog\sicstus
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_swilgt.js"""; Description: "SWI-Prolog integration"; Components: prolog\swi
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_xsblgt.js"""; Description: "XSB integration"; Components: prolog\xsb
Filename: "{cmd}"; Parameters: "/C cscript ""{app}\scripts\make_yaplgt.js"""; Description: "YAP integration"; Components: prolog\yap

Filename: "{app}\RELEASE_NOTES.txt"; Description: "View the release notes"; Flags: postinstall shellexec skipifsilent
Filename: "{app}\INSTALL.txt"; Description: "Review the install instructions for completing your setup"; Flags: postinstall shellexec skipifsilent

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


Update create_install_wizard.iss

Update create_install_wizard.iss

#define AppName "Cloudify Windows Agent"
#define AppVersion GetEnv('VERSION')
#define AppMilestone GetEnv('PRERELEASE')
#define AppBuild GetEnv('BUILD')
#define AppPublisher "GigaSpaces Technologies"
#define AppURL "http://getcloudify.org/"

[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={{94B9D938-5123-4AC5-AA99-68F07F773DE2}
AppName={#AppName}
AppVersion={#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DefaultDirName={pf}\Cloudify
DisableProgramGroupPage=yes
OutputBaseFilename=cloudify-windows-agent_{#AppVersion}-{#AppMilestone}
Compression=lzma
SolidCompression=yes
ArchitecturesInstallIn64BitMode=
LicenseFile=source\license.txt
MinVersion=6.0
SetupIconFile=source\icons\Cloudify.ico
UninstallDisplayIcon={app}\Cloudify.ico
OutputDir=output\

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

[Files]
Source: "source\python\python.msi"; Flags: dontcopy nocompression
Source: "source\wheels\*.whl"; Flags: dontcopy
Source: "source\pip\*"; Flags: dontcopy
Source: "source\virtualenv\*"; Flags: dontcopy
Source: "source\icons\Cloudify.ico"; DestDir: "{app}"

[Tasks]
Name: "desktopicon"; Description: "Create a desktop icon";

[Icons]
Name: "{userdesktop}\Cloudify Agent"; Filename: "{cmd}"; Parameters: "/k ""{app}\Scripts\activate.bat"""; WorkingDir: "{app}"; IconFilename: "{app}\Cloudify.ico"; Tasks: "desktopicon";

[UninstallDelete]
;this is NOT recommended but in our case, no user data here
Type: "filesandordirs"; Name: "{app}"

[Code]
const
  mainPackageName = 'cloudify-agent';
  //Registry key path
  RegPythonPath = 'SOFTWARE\Python\PythonCore\2.7\InstallPath';
  //Error messages
  errPythonMissing = 'Python installation was not found. In order to install {#AppName} you will need Python installed. Proceed to Python 2.7 installation?';
  errPipMissing = 'Pip was not found. Pip is a package management tool that is required to successfully install {#AppName}. Would you like to install it?';
  errVenvMissing = 'Virtualenv was not found. Virtualenv is a python environment managment tool that is required to successfully install {#AppName}. Would you like to install it?';
  errUnexpected = 'Unexpected error. Check installation logs.';
  infoPythonUninstall = 'Cloudify uninstaller will not remove Python as a safety precaution. Uninstalling Python should be done independently by the user.';

function getPythonDir(): String;
var
  InstallPath: String;
begin
  RegQueryStringValue(HKLM, RegPythonPath, '', InstallPath);
  RegQueryStringValue(HKCU, RegPythonPath, '', InstallPath);
  Result := InstallPath;
end;

function isPythonInstalled(): Boolean;
begin
  if getPythonDir <> '' then
      Result := True
  else
      Result := False;
end;

function getPythonPath(): String;
var
  PythonPath: String;
begin
  if isPythonInstalled then begin
    PythonPath := AddBackslash(getPythonDir) + 'python.exe';
    if FileExists(PythonPath) then
      Result := PythonPath
  end;
end;

function runPythonSetup(): Boolean;
var
  PythonArgs: String;
  InstallerPath: String;
  ErrorCode: Integer;
begin
  ExtractTemporaryFile('python.msi');
  InstallerPath := Expandconstant('{tmp}\python.msi');
  PythonArgs := 'ADDDEFAULT=pip_feature';
  if WizardSilent then
    PythonArgs := PythonArgs + ' /qn';
  ShellExec('', InstallerPath, PythonArgs, '', SW_SHOW, ewWaituntilterminated, ErrorCode);

  if Errorcode <> 0 then
    Result := False
  else
    Result := True;
end;

function getPipPath(): String;
var
  PipPath: String;
begin
  if isPythonInstalled then begin
    PipPath := AddBackslash(getPythonDir) + 'Scripts\pip.exe';
    if FileExists(PipPath) then
      Result := PipPath
  end;
end;

function isPipInstalled(): Boolean;
begin
  if getPipPath <> '' then
      Result := True
  else
      Result := False;
end;

function runPipSetup(): Boolean;
var
  GetPipArgs: String;
  ErrorCode: Integer;
begin
  if isPythonInstalled then begin
    ExtractTemporaryFiles('*.whl');
    ExtractTemporaryFile('get-pip.py');
    GetPipArgs := 'get-pip.py --use-wheel --no-index --find-links .';
    ShellExec('', getPythonPath, GetPipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

    if Errorcode <> 0 then
      Result := False
    else
      Result := True;
    end;
end;

function getVenvPath(): String;
var
  VenvPath: String;
begin
  if isPythonInstalled then begin
    VenvPath := AddBackslash(getPythonDir) + 'Scripts\virtualenv.exe';
    if FileExists(VenvPath) then
      Result := VenvPath
  end;
end;

function isVenvInstalled(): Boolean;
begin
  if getVenvPath <> '' then
      Result := True
  else
      Result := False;
end;

function runVenvSetup(): Boolean;
var
  GetPipArgs: String;
  ErrorCode: Integer;
begin
  if isPythonInstalled then begin
    ExtractTemporaryFiles('*.whl');
    GetPipArgs := 'install --use-wheel --no-index --find-links . virtualenv';
    ShellExec('', getPipPath, GetPipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

    if Errorcode <> 0 then
      Result := False
    else
      Result := True;
    end;
end;

function runVenvInitialization(): Boolean;
var
  ErrorCode: Integer;
begin
  Exec(getVenvPath, Expandconstant('--clear "{app}"'), Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

  if Errorcode <> 0 then
    Result := False
  else
    Result := True;
end;

function runWheelsInstall(): Boolean;
var
  PipArgs: String;
  ErrorCode: Integer;
begin
  ExtractTemporaryFiles('*.whl');

  if not (isVenvInstalled and runVenvInitialization) then begin
    Result := False;
    Exit;
  end;

  //Main wheels install
  PipArgs := Expandconstant('/c set "VIRTUAL_ENV={app}" && set "PATH={app}\Scripts;%PATH%" && pip install --pre --use-wheel --no-index --find-links . --force-reinstall --ignore-installed ' + mainPackageName);
  Exec(Expandconstant('{sys}\cmd.exe'), PipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

  //Install diamond
  PipArgs := Expandconstant('/c set "VIRTUAL_ENV={app}" && set "PATH={app}\Scripts;%PATH%" && pip install --pre --use-wheel --no-index --find-links . --force-reinstall --ignore-installed cloudify-diamond-plugin');
  Exec(Expandconstant('{sys}\cmd.exe'), PipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

  if Errorcode <> 0 then
    Result := False
  else
    Result := True;
end;

//wrap MsgBox to handle silent install case
function getUserResponse(Message: String): Integer;
begin
  if not WizardSilent then
    Result := MsgBox(Message, mbError, MB_OKCANCEL)
  else
    Result := IDOK;
end;

//Pre-Assumptions: Python and pip are installed
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then begin
    if not runWheelsInstall then
      RaiseException(errUnexpected);
  end;
end;

//Check for pre-requirements (Python, Pip, Virtualenv)
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  UserResponse: Integer;
begin
  if not isPythonInstalled then begin
    UserResponse := getUserResponse(errPythonMissing);
    if UserResponse <> IDOK then begin
      Result := 'Installation cannot continue without Python installed';
      Exit;
    end
    else if not runPythonSetup then begin
      Result := 'Python setup failed';
      Exit;
    end;
  end;

  if not isPipInstalled then begin
    UserResponse := getUserResponse(errPipMissing)
    if UserResponse <> IDOK then begin
      Result := 'Installation cannot continue without Pip installed';
      exit;
    end
    else if not runPipSetup then begin
      Result := 'Pip installation failed';
      Exit;
    end;
  end;

  if not isVenvInstalled then begin
    UserResponse := getUserResponse(errVenvMissing)
    if UserResponse <> IDOK then begin
      Result := 'Installation cannot continue without Virtualenv installed';
      Exit;
    end
    else if not runVenvSetup then begin
      Result := 'Virtualenv installation failed';
      Exit;
    end;
  end;
end;

//Display info message when install done about Python uninstall
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if (CurUninstallStep = usPostUninstall) and (not UninstallSilent) then
    MsgBox(infoPythonUninstall, mbInformation, MB_OK);
end;

#define AppName "Cloudify Windows Agent"
#define AppVersion GetEnv('VERSION')
#define AppMilestone GetEnv('PRERELEASE')
#define AppBuild GetEnv('BUILD')
#define AppPublisher "GigaSpaces Technologies"
#define AppURL "http://getcloudify.org/"

[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={{94B9D938-5123-4AC5-AA99-68F07F773DE2}
AppName={#AppName}
AppVersion={#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DefaultDirName={pf}\Cloudify
DisableProgramGroupPage=yes
OutputBaseFilename=cloudify-windows-agent_{#AppVersion}-{#AppMilestone}
Compression=lzma
SolidCompression=yes
ArchitecturesInstallIn64BitMode=
LicenseFile=source\license.txt
MinVersion=6.0
SetupIconFile=source\icons\Cloudify.ico
UninstallDisplayIcon={app}\Cloudify.ico
OutputDir=output\

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

[Files]
Source: "source\python\python.msi"; Flags: dontcopy nocompression
Source: "source\wheels\*.whl"; Flags: dontcopy
Source: "source\pip\*"; Flags: dontcopy
Source: "source\virtualenv\*"; Flags: dontcopy
Source: "source\icons\Cloudify.ico"; DestDir: "{app}"

[Tasks]
Name: "desktopicon"; Description: "Create a desktop icon";

[Icons]
Name: "{userdesktop}\Cloudify Agent"; Filename: "{cmd}"; Parameters: "/k ""{app}\Scripts\activate.bat"""; WorkingDir: "{app}"; IconFilename: "{app}\Cloudify.ico"; Tasks: "desktopicon";

[UninstallDelete]
;this is NOT recommended but in our case, no user data here
Type: "filesandordirs"; Name: "{app}"

[Code]
const
  mainPackageName = 'cloudify-agent';
  //Registry key path
  RegPythonPath = 'SOFTWARE\Python\PythonCore\2.7\InstallPath';
  //Error messages
  errPythonMissing = 'Python installation was not found. In order to install {#AppName} you will need Python installed. Procceed to Python 2.7 installation?';
  errPipMissing = 'Pip was not found. Pip is a package management tool that is required to successfully install {#AppName}. Would you like to install it?';
  errVenvMissing = 'Virtualenv was not found. Virtualenv is a python environment managment tool that is required to successfully install {#AppName}. Would you like to install it?';
  errUnexpected = 'Unexpected error. Check install logs';
  infoPythonUninstall = 'Cloudify uninstaller will not remove Python as a safety precaution. Uninstalling Python should be done independently by the user';

function getPythonDir(): String;
var
  InstallPath: String;
begin
  RegQueryStringValue(HKLM, RegPythonPath, '', InstallPath);
  RegQueryStringValue(HKCU, RegPythonPath, '', InstallPath);
  Result := InstallPath;
end;

function isPythonInstalled(): Boolean;
begin
  if getPythonDir <> '' then
      Result := True
  else
      Result := False;
end;

function getPythonPath(): String;
var
  PythonPath: String;
begin
  if isPythonInstalled then begin
    PythonPath := AddBackslash(getPythonDir) + 'python.exe';
    if FileExists(PythonPath) then
      Result := PythonPath
  end;
end;

function runPythonSetup(): Boolean;
var
  PythonArgs: String;
  InstallerPath: String;
  ErrorCode: Integer;
begin
  ExtractTemporaryFile('python.msi');
  InstallerPath := Expandconstant('{tmp}\python.msi');
  PythonArgs := 'ADDDEFAULT=pip_feature';
  if WizardSilent then
    PythonArgs := PythonArgs + ' /qn';
  ShellExec('', InstallerPath, PythonArgs, '', SW_SHOW, ewWaituntilterminated, ErrorCode);

  if Errorcode <> 0 then
    Result := False
  else
    Result := True;
end;

function getPipPath(): String;
var
  PipPath: String;
begin
  if isPythonInstalled then begin
    PipPath := AddBackslash(getPythonDir) + 'Scripts\pip.exe';
    if FileExists(PipPath) then
      Result := PipPath
  end;
end;

function isPipInstalled(): Boolean;
begin
  if getPipPath <> '' then
      Result := True
  else
      Result := False;
end;

function runPipSetup(): Boolean;
var
  GetPipArgs: String;
  ErrorCode: Integer;
begin
  if isPythonInstalled then begin
    ExtractTemporaryFiles('*.whl');
    ExtractTemporaryFile('get-pip.py');
    GetPipArgs := 'get-pip.py --use-wheel --no-index --find-links .';
    ShellExec('', getPythonPath, GetPipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

    if Errorcode <> 0 then
      Result := False
    else
      Result := True;
    end;
end;

function getVenvPath(): String;
var
  VenvPath: String;
begin
  if isPythonInstalled then begin
    VenvPath := AddBackslash(getPythonDir) + 'Scripts\virtualenv.exe';
    if FileExists(VenvPath) then
      Result := VenvPath
  end;
end;

function isVenvInstalled(): Boolean;
begin
  if getVenvPath <> '' then
      Result := True
  else
      Result := False;
end;

function runVenvSetup(): Boolean;
var
  GetPipArgs: String;
  ErrorCode: Integer;
begin
  if isPythonInstalled then begin
    ExtractTemporaryFiles('*.whl');
    GetPipArgs := 'install --use-wheel --no-index --find-links . virtualenv';
    ShellExec('', getPipPath, GetPipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

    if Errorcode <> 0 then
      Result := False
    else
      Result := True;
    end;
end;

function runVenvInitialization(): Boolean;
var
  ErrorCode: Integer;
begin
  Exec(getVenvPath, Expandconstant('--clear "{app}"'), Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

  if Errorcode <> 0 then
    Result := False
  else
    Result := True;
end;

function runWheelsInstall(): Boolean;
var
  PipArgs: String;
  ErrorCode: Integer;
begin
  ExtractTemporaryFiles('*.whl');

  if not (isVenvInstalled and runVenvInitialization) then begin
    Result := False;
    Exit;
  end;

  //Main wheels install
  PipArgs := Expandconstant('/c set "VIRTUAL_ENV={app}" && set "PATH={app}\Scripts;%PATH%" && pip install --pre --use-wheel --no-index --find-links . --force-reinstall --ignore-installed ' + mainPackageName);
  Exec(Expandconstant('{sys}\cmd.exe'), PipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

  //Install diamond
  PipArgs := Expandconstant('/c set "VIRTUAL_ENV={app}" && set "PATH={app}\Scripts;%PATH%" && pip install --pre --use-wheel --no-index --find-links . --force-reinstall --ignore-installed cloudify-diamond-plugin');
  Exec(Expandconstant('{sys}\cmd.exe'), PipArgs, Expandconstant('{tmp}'), SW_SHOW, ewWaituntilterminated, ErrorCode);

  if Errorcode <> 0 then
    Result := False
  else
    Result := True;
end;

//wrap MsgBox to handle silent install case
function getUserResponse(Message: String): Integer;
begin
  if not WizardSilent then
    Result := MsgBox(Message, mbError, MB_OKCANCEL)
  else
    Result := IDOK;
end;

//Pre-Assumptions: Python and pip are installed
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then begin
    if not runWheelsInstall then
      RaiseException(errUnexpected);
  end;
end;

//Check for pre-requirements (Python, Pip, Virtualenv)
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  UserResponse: Integer;
begin
  if not isPythonInstalled then begin
    UserResponse := getUserResponse(errPythonMissing);
    if UserResponse <> IDOK then begin
      Result := 'Installation cannot continue without Python installed';
      Exit;
    end
    else if not runPythonSetup then begin
      Result := 'Python setup failed';
      Exit;
    end;
  end;

  if not isPipInstalled then begin
    UserResponse := getUserResponse(errPipMissing)
    if UserResponse <> IDOK then begin
      Result := 'Installation cannot continue without Pip installed';
      exit;
    end
    else if not runPipSetup then begin
      Result := 'Pip installation failed';
      Exit;
    end;
  end;

  if not isVenvInstalled then begin
    UserResponse := getUserResponse(errVenvMissing)
    if UserResponse <> IDOK then begin
      Result := 'Installation cannot continue without Virtualenv installed';
      Exit;
    end
    else if not runVenvSetup then begin
      Result := 'Virtualenv installation failed';
      Exit;
    end;
  end;
end;

//Display info message when install done about Python uninstall
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if (CurUninstallStep = usPostUninstall) and (not UninstallSilent) then
    MsgBox(infoPythonUninstall, mbInformation, MB_OK);
end;