;.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,., ; ; ;Copyright (c) 2002-2010 Jernej Simončič ; ; ; ;This software is provided 'as-is', without any express or implied ; ;warranty. In no event will the authors be held liable for any damages ; ;arising from the use of this software. ; ; ; ;Permission is granted to anyone to use this software for any purpose, ; ;including commercial applications, and to alter it and redistribute it ; ;freely, subject to the following restrictions: ; ; ; ; 1. The origin of this software must not be misrepresented; you must ; ; not claim that you wrote the original software. If you use this ; ; software in a product, an acknowledgment in the product ; ; documentation would be appreciated but is not required. ; ; ; ; 2. Altered source versions must be plainly marked as such, and must ; ; not be misrepresented as being the original software. ; ; ; ; 3. This notice may not be removed or altered from any source ; ; distribution. ; ;.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.; ; ;Install script for PIKA and GTK+ ;requires Inno Setup 6 ; ;See directories.isi ; ;Changelog: ; ;2012-05-05 ;- check for SSE support ;- remove obsolete 2.6 plugins when installing over 2.6.12 combined installer ; ;2011-12-18 ;- display a picture on the first install screen ;- add a development version warning back ;- clean gegl's DLLs on install as some files have changed names ; ;2011-08-30 ;- only uninstall previous PIKA version when installing over existing installation ; TODO: offer the option to uninstall 32bit version when installing on x64 system ;- install 32bit plugins to same directory as 64bit plugins on x64 installs to ; avoid problems when upgrading ; ;2010-07-08 ;- clean up entire Python subdirectory (since the .pyc files are generated when ; scripts are run) ;- use crHand instead of crHandPoint for the billboard URL ; ;2010-07-02 ;- add libraries for compatibility with old 32-bit plug-ins as a component ;- remove a few unused RTF ready-memo related things ;- uninst.inf is now processed as the first step of uninstall, as otherwise the ; uninstaller could leave behind empty directories ; ;2010-06-29 ;- fix SuppressibleMsgBox calls to use proper button ID for default button ;- simplify the wizard - skip Welcome page, and make the Next button from ; InfoBefore/License page invoke install immediately (custom install is still ; possible by clicking the Customize button) ; ;2010-05-15 ;- rewrote script mostly from scratch ;- combine 32 and 64bit PIKA versions to a single installer ; - install enough 32bit support files even with 64bit version to allow running 32bit ; plug-ins on 64bit version (used by Python scriptin support [as there's no 64-bit ; PyGTK+ on Windows available yet] and TWAIN plug-in, which only works in 32-bit ; version) ;- Python with PyGTK is included in the installer now ;- install PIKA to new directory by default ({pf}\PIKA 2 instead of {pf}\PIKA-2.0) ;- uninstall previous PIKA versions as the first step of install (both 32 and 64-bit) ; - require reboot if installing to directory from which PIKA was just uninstalled, ; and this directory wasn't removed by the uninstaller; the installer will continue ; automatically after reboot ;- fixed a long standing bug where "Open with PIKA" menu entries would be left after ; uninstalling ; #pragma option -e+ #ifndef VERSION #error VERSION must be defined #endif #ifndef PIKA_DIR #error PIKA_DIR must be defined #endif #ifndef DIR32 #error DIR32 must be defined #endif #ifndef DIR64 #error DIR64 must be defined #endif #ifndef DEPS_DIR #error DEPS_DIR must be defined #endif #ifndef DDIR32 #error DDIR32 must be defined #endif #ifndef DDIR64 #error DDIR64 must be defined #endif ; Optional: PYTHON, LUA, DEBUG_SYMBOLS, NOCOMPRESSION, NOFILES, DEVEL #define X86 1 #define X64 2 #define ARM64 3 #include "directories.isi" #include "version.isi" [Setup] AppName=PIKA #if Defined(DEVEL) && DEVEL != "" AppID=PIKA-{#MAJOR}.{#MINOR} #else AppID=PIKA-{#MAJOR} #endif VersionInfoVersion={#VERSION} #if !defined(REVISION) AppVerName=PIKA {#VERSION} #else AppVerName=PIKA {#VERSION}-{#REVISION} #endif AppPublisherURL=https://heckin.technology/AlderconeStudio/PIKApp/ AppSupportURL=https://heckin.technology/AlderconeStudio/PIKApp/docs/ AppUpdatesURL=https://heckin.technology/AlderconeStudio/PIKApp/ AppPublisher=The PIKA Team AppVersion={#VERSION} DisableProgramGroupPage=yes DisableWelcomePage=no DisableDirPage=auto AlwaysShowDirOnReadyPage=yes ChangesEnvironment=yes #if Defined(DEVEL) && DEVEL != "" DefaultDirName={autopf}\PIKA {#MAJOR}.{#MINOR} LZMANumBlockThreads=4 LZMABlockSize=76800 #else DefaultDirName={autopf}\PIKA {#MAJOR} #endif ;AllowNoIcons=true FlatComponentsList=yes InfoBeforeFile=gpl+python.rtf ChangesAssociations=true WizardImageFile=windows-installer-intro-big.bmp WizardImageStretch=yes WizardSmallImageFile=wilber.bmp UninstallDisplayIcon={app}\bin\pika-{#MAJOR}.{#MINOR}.exe UninstallFilesDir={app}\uninst MinVersion=6.1 ArchitecturesInstallIn64BitMode=x64 arm64 #ifdef NOCOMPRESSION ;UseSetupLdr=no OutputDir=_Output\unc Compression=none ;InternalCompressLevel=0 DiskSpanning=yes DiskSliceSize=max #else OutputDir=_Output Compression=lzma2/ultra64 InternalCompressLevel=ultra SolidCompression=yes LZMAUseSeparateProcess=yes LZMANumFastBytes=273 ; Increasing dictionary size may improve compression ratio at the ; expense of memory requirement. We run into "Out of memory" error in ; the CI. ;LZMADictionarySize=524288 ;SignTool=Default ;SignedUninstaller=yes ;SignedUninstallerDir=_Uninst #endif //NOCOMPRESSION #if !defined(REVISION) OutputBaseFileName=pika-{#VERSION}-setup OutputManifestFile=pika-{#VERSION}-setup.txt #else OutputBaseFileName=pika-{#VERSION}-{#REVISION}-setup OutputManifestFile=pika-{#VERSION}-{#REVISION}-setup.txt #endif PrivilegesRequiredOverridesAllowed=dialog [Languages] Name: "en"; MessagesFile: "compiler:Default.isl,lang\en.setup.isl" Name: "be"; MessagesFile: "compiler:Languages\Unofficial\Belarusian.isl,lang\be.setup.isl" Name: "bg"; MessagesFile: "compiler:Languages\Bulgarian.isl,lang\bg.setup.isl" Name: "ca"; MessagesFile: "compiler:Languages\Catalan.isl,lang\ca.setup.isl" Name: "cs"; MessagesFile: "compiler:Languages\Czech.isl,lang\cs.setup.isl" Name: "da"; MessagesFile: "compiler:Languages\Danish.isl,lang\da.setup.isl" Name: "de"; MessagesFile: "compiler:Languages\German.isl,lang\de.setup.isl" Name: "el"; MessagesFile: "compiler:Languages\Unofficial\Greek.isl,lang\el.setup.isl" Name: "en_GB"; MessagesFile: "compiler:Languages\Unofficial\EnglishBritish.isl,lang\en_GB.setup.isl" Name: "eo"; MessagesFile: "compiler:Languages\Unofficial\Esperanto.isl,lang\eo.setup.isl" Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl,lang\es.setup.isl" Name: "eu"; MessagesFile: "compiler:Languages\Unofficial\Basque.isl,lang\eu.setup.isl" Name: "fi"; MessagesFile: "compiler:Languages\Finnish.isl,lang\fi.setup.isl" Name: "fr"; MessagesFile: "compiler:Languages\French.isl,lang\fr.setup.isl" Name: "gl"; MessagesFile: "compiler:Languages\Unofficial\Galician.isl,lang\gl.setup.isl" Name: "he"; MessagesFile: "compiler:Languages\Hebrew.isl,lang\he.setup.isl" Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl,lang\hu.setup.isl" ;Name: "hr"; MessagesFile: "compiler:Languages\Unofficial\Croatian.isl,lang\hr.setup.isl" Name: "id"; MessagesFile: "compiler:Languages\Unofficial\Indonesian.isl,lang\id.setup.isl" Name: "is"; MessagesFile: "compiler:Languages\Icelandic.isl,lang\is.setup.isl" Name: "it"; MessagesFile: "compiler:Languages\Italian.isl,lang\it.setup.isl" Name: "ja"; MessagesFile: "compiler:Languages\Japanese.isl,lang\ja.setup.isl" Name: "ka"; MessagesFile: "compiler:Languages\Unofficial\Georgian.isl,lang\ka.setup.isl" Name: "kab"; MessagesFile: "compiler:Default.isl,lang\kab.isl,lang\kab.setup.isl" Name: "ko"; MessagesFile: "compiler:Languages\Korean.isl,lang\ko.setup.isl" Name: "lt"; MessagesFile: "compiler:Languages\Unofficial\Lithuanian.isl,lang\lt.setup.isl" Name: "lv"; MessagesFile: "compiler:Languages\Unofficial\Latvian.isl,lang\lv.setup.isl" Name: "mr"; MessagesFile: "compiler:Languages\Unofficial\Marathi.islu,lang\mr.setup.isl" Name: "ms"; MessagesFile: "compiler:Languages\Unofficial\Malaysian.isl,lang\ms.setup.isl" Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl,lang\nl.setup.isl" Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl,lang\pl.setup.isl" Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl,lang\pt.setup.isl" Name: "pt_BR"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl,lang\pt_BR.setup.isl" Name: "ro"; MessagesFile: "compiler:Languages\Unofficial\Romanian.isl,lang\ro.setup.isl" Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl,lang\ru.setup.isl" Name: "sk"; MessagesFile: "compiler:Languages\Slovak.isl,lang\sk.setup.isl" Name: "sl"; MessagesFile: "compiler:Languages\Slovenian.isl,lang\sl.setup.isl" Name: "sv"; MessagesFile: "compiler:Languages\Unofficial\Swedish.isl,lang\sv.setup.isl" Name: "tr"; MessagesFile: "compiler:Languages\Turkish.isl,lang\tr.setup.isl" Name: "uk"; MessagesFile: "compiler:Languages\Ukrainian.isl,lang\uk.setup.isl" Name: "vi"; MessagesFile: "compiler:Languages\Unofficial\Vietnamese.isl,lang\vi.setup.isl" Name: "zh_CN"; MessagesFile: "compiler:Languages\Unofficial\ChineseSimplified.isl,lang\zh_CN.setup.isl" Name: "zh_TW"; MessagesFile: "compiler:Languages\Unofficial\ChineseTraditional.isl,lang\zh_TW.setup.isl" ;Name: "ro"; MessagesFile: "Romanian.islu,ro.setup.islu" [Types] ;Name: normal; Description: "{cm:TypeTypical}" Name: full; Description: "{cm:TypeFull}" Name: compact; Description: "{cm:TypeCompact}" Name: custom; Description: "{cm:TypeCustom}"; Flags: iscustom [Components] Name: pika32; Description: "{cm:ComponentsGimp,{#VERSION}}"; Types: full compact custom; Flags: fixed; Check: Check3264('32') Name: pika64; Description: "{cm:ComponentsGimp,{#VERSION}}"; Types: full compact custom; Flags: fixed; Check: Check3264('x64') Name: pikaARM64; Description: "{cm:ComponentsGimp,{#VERSION}}"; Types: full compact custom; Flags: fixed; Check: Check3264('arm64') Name: deps32; Description: "{cm:ComponentsDeps,{#GTK_VERSION}}"; Types: full compact custom; Flags: checkablealone fixed; Check: Check3264('32') Name: deps64; Description: "{cm:ComponentsDeps,{#GTK_VERSION}}"; Types: full compact custom; Flags: checkablealone fixed; Check: Check3264('x64') Name: depsARM64; Description: "{cm:ComponentsDeps,{#GTK_VERSION}}"; Types: full compact custom; Flags: checkablealone fixed; Check: Check3264('arm64') #ifdef DEBUG_SYMBOLS Name: debug; Description: "{cm:ComponentsDebug}"; Types: full custom; Flags: disablenouninstallwarning #endif Name: gs; Description: "{cm:ComponentsGhostscript}"; Types: full custom Name: loc; Description: "{cm:ComponentsTranslations}"; Types: full custom Name: mypaint; Description: "{cm:ComponentsMyPaint}"; Types: full custom #ifdef PYTHON Name: py; Description: "{cm:ComponentsPython}"; Types: full custom #endif #ifdef LUA Name: lua; Description: "{cm:ComponentsLua}"; Types: full custom #endif Name: pika32on64; Description: "{cm:ComponentsGimp32}"; Types: full custom; Flags: checkablealone; Check: Check3264('64') [Tasks] Name: desktopicon; Description: "{cm:AdditionalIconsDesktop}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Icons] #define ICON_VERSION=MAJOR + "." + MINOR + "." + MICRO Name: "{autoprograms}\PIKA {#ICON_VERSION}"; Filename: "{app}\bin\pika-{#MAJOR}.{#MINOR}.exe"; WorkingDir: "%USERPROFILE%"; Comment: "PIKA {#VERSION}" Name: "{autodesktop}\PIKA {#ICON_VERSION}"; Filename: "{app}\bin\pika-{#MAJOR}.{#MINOR}.exe"; WorkingDir: "%USERPROFILE%"; Comment: "PIKA {#VERSION}"; Tasks: desktopicon [Files] ;setup files Source: "windows-installer-intro-small.bmp"; Flags: dontcopy #ifndef DEVEL Source: "installsplash.bmp"; Flags: dontcopy Source: "installsplash_small.bmp"; Flags: dontcopy #else Source: "installsplash-devel.bmp"; Destname: "installsplash.bmp"; Flags: dontcopy Source: "installsplash_small-devel.bmp"; Destname: "installsplash_small.bmp"; Flags: dontcopy #endif #ifndef NOFILES ;files common to both 32 and 64-bit versions Source: "{#PIKA_DIR32}\etc\*"; DestDir: "{app}\etc"; Components: pika32 or pika64 or pikaARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIR32}\lib\pika\{#DIR_VER}\environ\*"; DestDir: "{app}\lib\pika\{#DIR_VER}\environ"; Components: pika32 or pika64 or pikaARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIR32}\lib\pika\{#DIR_VER}\interpreters\*"; DestDir: "{app}\lib\pika\{#DIR_VER}\interpreters"; Components: pika32 or pika64 or pikaARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIR32}\share\pika\*"; DestDir: "{app}\share\pika"; Components: pika32 or pika64 or pikaARM64; Flags: recursesubdirs createallsubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIR32}\share\metainfo\*"; DestDir: "{app}\share\metainfo"; Components: pika32 or pika64 or pikaARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\glib-2.0\schemas\*"; DestDir: "{app}\share\glib-2.0\schemas"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs createallsubdirs restartreplace uninsrestartdelete ignoreversion ;Source: "{#DEPS_DIR32}\share\enchant\*"; DestDir: "{app}\share\enchant"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\libwmf\*"; DestDir: "{app}\share\libwmf"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\icons\*"; DestDir: "{app}\share\icons"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\xml\*"; DestDir: "{app}\share\xml"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\poppler\*.*"; DestDir: "{app}\share\poppler"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\libthai\*"; DestDir: "{app}\share\libthai"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\locale\*"; DestDir: "{app}\share\locale"; Components: loc; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIR32}\share\locale\*"; DestDir: "{app}\share\locale"; Components: loc; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion ;configure pika with --enable-bundled-mypaint-brushes for the correct path to ;be picked by pika Source: "{#DEPS_DIR32}\share\mypaint-data\*"; DestDir: "{app}\share\mypaint-data"; Components: mypaint; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\etc\fonts\*"; DestDir: "{app}\etc\fonts"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\etc\gtk-3.0\*"; DestDir: "{app}\etc\gtk-3.0"; Components: deps32 or deps64 or depsARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#DEPS_DIR32}\share\ghostscript\*"; Excludes: "*\doc\*"; DestDir: "{app}\share\ghostscript"; Components: gs and (pika32 or pika64 or pikaARM64); Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion #ifdef PYTHON ;*.py files are the same on 32 and 64-bit Source: "{#PIKA_DIR32}\lib\pika\{#DIR_VER}\plug-ins\*.py"; DestDir: "{app}\lib\pika\{#DIR_VER}\plug-ins"; Components: py; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion #endif ;x86_64 #define PLATFORM X64 #include "files.isi" ;AArch64 #define PLATFORM ARM64 #include "files.isi" ;i686 #define PLATFORM X86 #include "files.isi" ;special case, since 64bit version doesn't work, and is excluded in files.isi Source: "{#PIKA_DIR32}\lib\pika\{#DIR_VER}\plug-ins\twain.exe"; DestDir: "{app}\lib\pika\{#DIR_VER}\plug-ins"; Components: pika32; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion ;32-on-64bit #include "32on64.isi" ;prefer 32bit twain plugin over 64bit because 64bit twain drivers are rare Source: "{#PIKA_DIR32}\lib\pika\{#DIR_VER}\plug-ins\twain\twain.exe"; DestDir: "{app}\lib\pika\{#DIR_VER}\plug-ins\twain"; Components: pika32on64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIR64}\lib\pika\{#DIR_VER}\plug-ins\twain\twain.exe"; DestDir: "{app}\lib\pika\{#DIR_VER}\plug-ins\twain"; Components: (not pika32on64) and pika64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion Source: "{#PIKA_DIRA64}\lib\pika\{#DIR_VER}\plug-ins\twain\twain.exe"; DestDir: "{app}\lib\pika\{#DIR_VER}\plug-ins\twain"; Components: (not pika32on64) and pikaARM64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion ;special case due to MS-Windows engine Source: "{#DEPS_DIR32}\etc\gtk-3.0\*"; DestDir: "{app}\32\etc\gtk-3.0"; Components: pika32on64; Flags: recursesubdirs restartreplace uninsrestartdelete ignoreversion ;upgrade zlib1.dll in System32 if it's present there to avoid breaking plugins ;sharedfile flag will ensure that the upgraded file is left behind on uninstall to avoid breaking other programs that use the file Source: "{#DEPS_DIR32}\bin\zlib1.dll"; DestDir: "{sys}"; Components: pika32 or pika64 or pikaARM64; Flags: restartreplace sharedfile 32bit uninsrestartdelete comparetimestamp; Check: BadSysDLL('zlib1.dll',32) Source: "{#DEPS_DIR64}\bin\zlib1.dll"; DestDir: "{sys}"; Components: pika64; Flags: restartreplace sharedfile uninsrestartdelete comparetimestamp; Check: BadSysDLL('zlib1.dll',64) ;overridden configuration files #include "configoverride.isi" #endif //NOFILES [InstallDelete] Type: files; Name: "{app}\bin\pika-?.?.exe" Type: files; Name: "{app}\bin\pika-?.??.exe" Type: files; Name: "{app}\bin\pika-console-?.?.exe" Type: files; Name: "{app}\bin\pika-console-?.??.exe" Type: files; Name: "{app}\lib\gegl-0.1\*.dll" ;obsolete plugins from pika 2.6 Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pdf.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\gee.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\gee-zoom.exe" ;old Python Type: filesandordirs; Name: "{app}\Python\*" Type: dirifempty; Name: "{app}\Python" ;remove incompatible version shipped with 2.8 Type: files; Name: "{app}\bin\zlib1.dll" Type: files; Name: "{app}\32\bin\zlib1.dll" ;old ghostscript Type: filesandordirs; Name: "{app}\share\ghostscript\*" ;obsolete plugins from pika 2.8 Type: files; Name: "{app}\lib\pika\2.0\plug-ins\pyconsole.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\python-console.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\metadata.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-psd-save.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-psd-load.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\alien-map.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\antialias.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\apply-canvas.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\blur-gauss.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\blur-gauss-selective.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\blur-motion.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\bump-map.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\channel-mixer.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\color-exchange.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\color-rotate.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\color-to-alpha.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\contrast-stretch.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\contrast-stretch-hsv.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\convolution-matrix.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\crop-auto.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\cubism.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\deinterlace.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\diffraction.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\displace.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\edge.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\edge-laplace.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\edge-sobel.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\engrave.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-raw.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-tiff-load.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-tiff-save.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-uri.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\illusion.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\iwarp.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\lcms.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\lens-apply.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\lens-distortion.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\lens-flare.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\maze.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\mosaic.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\noise-hsv.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\noise-randomize.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\noise-rgb.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\noise-solid.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\noise-spread.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\nova.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\pixelize.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\plasma.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\polar-coords.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\red-eye-removal.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\ripple.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\rotate.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\semi-flatten.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\shift.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\sinus.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\threshold-alpha.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\tile-glass.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\tile-paper.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\tile-seamless.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\value-invert.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\value-propagate.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\video.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\waves.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\whirl-pinch.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\win-snap.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\wind.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\text-brush.py" ;<2.10.6 plug-ins Type: files; Name: "{app}\lib\pika\2.0\plug-ins\align-layers.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\animation-optimize.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\animation-play.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\blinds.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\blur.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\border-average.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\busy-dialog.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\cartoon.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\checkerboard.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\cml-explorer.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\color-cube-analyze.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\color-enhance.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\colorify.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\colormap-remap.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\compose.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\contrast-normalize.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\contrast-retinex.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\crop-zealous.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\curve-bend.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\decompose.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\depth-merge.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\despeckle.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\destripe.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\edge-dog.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\edge-neon.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\emboss.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-bmp.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-cel.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-compressor.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-csource.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-darktable.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-desktop-link.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-dicom.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-exr.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-faxg3.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-fits.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-fli.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-gbr.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-gegl.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-gif-load.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-gif-save.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-gih.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-glob.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-header.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-heif.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-html-table.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-ico.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-jp2-load.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-jpeg.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-mng.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pat.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pcx.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pdf-load.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pdf-save.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pix.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-png.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-pnm.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-ps.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-psd.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-psp.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-raw-data.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-raw-placeholder.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-rawtherapee.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-sgi.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-sunras.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-svg.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-tga.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-tiff.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-webp.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-wmf.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-xbm.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-xpm.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-xwd.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\film.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\filter-pack.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\flame.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\fractal-explorer.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\fractal-trace.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\gfig.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\pikaressionist.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\goat-exercise.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\gradient-flare.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\gradient-map.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\grid.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\guillotine.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\help-browser.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\help.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\hot.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\ifs-compose.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\imagemap.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\jigsaw.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\lighting.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\map-object.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\max-rgb.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\metadata-editor.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\metadata-viewer.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\newsprint.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\nl-filter.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\oilify.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\pagecurl.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\photocopy.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\plugin-browser.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\print.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\procedure-browser.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\qbist.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\sample-colorize.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\screenshot.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\script-fu.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\selection-to-path.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\sharpen.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\smooth-palette.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\softglow.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\sparkle.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\sphere-designer.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\tile-small.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\tile.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\twain.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\unit-editor.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\unsharp-mask.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\van-gogh-lic.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\warp.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\wavelet-decompose.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\web-browser.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\web-page.exe" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\colorxhtml.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\file-openraster.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\foggify.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\gradients-save-as-css.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\histogram-export.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\palette-offset.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\palette-sort.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\palette-to-gradient.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\py-slice.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\python-eval.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\python-console\pyconsole.py" Type: files; Name: "{app}\lib\pika\2.0\plug-ins\python-console\python-console.py" ;<2.99.14 plug-ins and modules Type: files; Name: "{app}\lib\pika\2.99\plug-ins\py-slice\py-slice.py" Type: files; Name: "{app}\lib\pika\2.99\plug-ins\benchmark-foreground-extract\benchmark-foreground-extract.py" ;Some typo in meson which we used for PIKA 2.99.12 installer. Type: files; Name: "{app}\lib\pika\2.99\modules\libcontroller-dx-input.dll" ;DLLs in plug-ins directory (see bug 796225) Type: files; Name: "{app}\lib\pika\2.0\plug-ins\*.dll" ;gegl 0.2 Type: filesandordirs; Name: "{app}\lib\gegl-0.2" ;old icons #ifndef DEVEL Type: files; Name: "{autoprograms}\PIKA 2.lnk" Type: files; Name: "{autodesktop}\PIKA 2.lnk" #endif ;get previous PIKA icon name from uninstall name in Registry #if Defined(DEVEL) && DEVEL != "" Type: files; Name: "{autoprograms}\PIKA {reg:HKA\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}.{#MINOR}_is1,DisplayVersion|PIKA {#MAJOR}.{#MINOR}}.lnk"; Check: CheckRegValueExists('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}.{#MINOR}_is1','DisplayVersion') Type: files; Name: "{autodesktop}\PIKA {reg:HKA\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}.{#MINOR}_is1,DisplayVersion|PIKA {#MAJOR}.{#MINOR}}.lnk"; Check: CheckRegValueExists('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}.{#MINOR}_is1','DisplayVersion') #else Type: files; Name: "{autoprograms}\PIKA {reg:HKA\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}_is1,DisplayVersion|PIKA {#MAJOR}}.lnk"; Check: CheckRegValueExists('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}_is1','DisplayVersion') Type: files; Name: "{autodesktop}\PIKA {reg:HKA\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}_is1,DisplayVersion|PIKA {#MAJOR}}.lnk"; Check: CheckRegValueExists('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PIKA-{#MAJOR}_is1','DisplayVersion') #endif ;32-bit Python Type: filesandordirs; Name: "{app}\32\lib\pika\2.0\python" Type: files; Name: "{app}\32\bin\python2w.exe" Type: files; Name: "{app}\32\bin\python2.exe" Type: files; Name: "{app}\32\bin\libpython2.7.dll" Type: filesandordirs; Name: "{app}\32\lib\python2.7" ;remove old babl and gegl plugins Type: filesandordirs; Name: "{app}\lib\babl-0.1" Type: filesandordirs; Name: "{app}\lib\gegl-0.4" [Registry] ;remove LIBTHAI_DICTDIR variable set by original 2.10.8 installer Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: none; ValueName: "LIBTHAI_DICTDIR"; Flags: deletevalue uninsdeletevalue noerror #include "associations.isi" [UninstallDelete] Type: files; Name: "{app}\uninst\uninst.inf" Type: files; Name: "{app}\lib\pika\{#DIR_VER}\interpreters\lua.interp" Type: files; Name: "{app}\lib\pika\{#DIR_VER}\environ\pypika.env" ;need to clean out all the generated .pyc files Type: filesandordirs; Name: "{app}\Python\*" [Code] function WideCharToMultiByte(CodePage: Cardinal; dwFlags: DWORD; lpWideCharStr: String; cchWideCharStr: Integer; lpMultiByteStr: PAnsiChar; cbMultiByte: Integer; lpDefaultChar: Integer; lpUsedDefaultChar: Integer): Integer; external 'WideCharToMultiByte@Kernel32 stdcall'; function MultiByteToWideChar(CodePage: Cardinal; dwFlags: DWORD; lpMultiByteStr: PAnsiChar; cbMultiByte: Integer; lpWideCharStr: String; cchWideChar: Integer): Integer; external 'MultiByteToWideChar@Kernel32 stdcall'; function GetLastError(): DWORD; external 'GetLastError@Kernel32 stdcall'; function GetSysColor(nIndex: Integer): DWORD; external 'GetSysColor@user32.dll stdcall'; function IsProcessorFeaturePresent(ProcessorFeature: DWORD): LongBool; external 'IsProcessorFeaturePresent@kernel32 stdcall'; //functions needed to get BPP function GetDC(hWnd: Integer): Integer; external 'GetDC@User32 stdcall'; function ReleaseDC(hWnd, hDC: Integer): Integer; external 'ReleaseDC@User32 stdcall'; function GetDeviceCaps(hDC, nIndex: Integer): Integer; external 'GetDeviceCaps@GDI32 stdcall'; procedure ComponentsListOnClick(pSender: TObject); forward; procedure SaveToUninstInf(const pText: AnsiString); forward; procedure CreateRunOnceEntry; forward; function RestartSetupAfterReboot(): Boolean; forward; procedure AssociationsCleanUp(); forward; const CP_ACP = 0; CP_UTF8 = 65001; COLOR_HOTLIGHT = 26; PF_XMMI_INSTRUCTIONS_AVAILABLE = 6; BITSPIXEL = 12; PLANES = 14; PIKA_URL = 'https://heckin.technology/AlderconeStudio/PIKApp/'; RTFHeader = '{\rtf1\deff0{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\fnil\fcharset2 Symbol;}}\viewkind4\uc1\fs16'; //RTFBullet = '{\pntext\f1\''B7\tab}'; RTFPara = '\par '; RunOnceName = 'Resume PIKA {#VERSION} install'; CONFIG_OVERRIDE_PARAM = 'configoverride'; UNINSTALL_MAX_WAIT_TIME = 10000; UNINSTALL_CHECK_TIME = 250; type TRemoveOldPIKAResult = (rogContinue, rogRestartRequired, rogUninstallFailed, rogCantUninstall); var lblComponentDescription: TNewStaticText; ReadyMemoRichText: String; WelcomeBitmapBottom: TBitmapImage; //pgSimple: TWizardPage; btnInstall, btnCustomize: TNewButton; InstallMode: (imNone, imSimple, imCustom, imRebootContinue); ConfigOverride: (coUndefined, coOverride, coDontOverride); Force32bitInstall: Boolean; asUninstInf: TArrayOfString; //uninst.inf contents (loaded at start of uninstall, executed at the end) #include "MessageWithURL.isi" function Check3264(const pWhich: String): Boolean; begin if pWhich = '64' then //x64 or arm64 Result := Is64BitInstallMode() and (not Force32bitInstall) else if pWhich = '32' then Result := (not Is64BitInstallMode()) or Force32bitInstall else if pWhich = 'x64' then Result := Is64BitInstallMode() and IsX64 and (not Force32bitInstall) else if pWhich = 'arm64' then Result := Is64BitInstallMode() and IsARM64 and (not Force32bitInstall) else RaiseException('Unknown check'); end; #include "utils.isi" //some programs improperly install libraries to the System32 directory, which then causes problems with plugins //this function checks if such file exists in System32, and lets setup update the file when it exists function BadSysDLL(const pFile: String; const pPlatform: Integer): Boolean; var OldRedir: Boolean; begin Result := False; if pPlatform = 64 then begin if Is64BitInstallMode() then //only check when installing in 64bit mode begin OldRedir := EnableFsRedirection(False); DebugMsg('BadSysDLL','64: ' + ExpandConstant('{sys}\' + pFile)); Result := FileExists(ExpandConstant('{sys}\' + pFile)); EnableFsRedirection(OldRedir); end; end else if pPlatform = 32 then begin if Is64BitInstallMode() then //check 32bit system directory on x64 windows begin DebugMsg('BadSysDLL','32on64: ' + ExpandConstant('{syswow64}\' + pFile)); Result := FileExists(ExpandConstant('{syswow64}\' + pFile)); end else begin DebugMsg('BadSysDLL','32: ' + ExpandConstant('{sys}\' + pFile)); Result := FileExists(ExpandConstant('{sys}\' + pFile)); end; end else begin RaiseException('Unsupported platform'); end; DebugMsg('BadSysDLL','Result: ' + BoolToStr(Result)); end; function CheckRegValueExists(const SubKeyName, ValueName: String): Boolean; begin Result := RegValueExists(HKEY_AUTO, SubKeyName, ValueName); DebugMsg('CheckRegValueExists',SubKeyName + ', ' + ValueName + ': ' + BoolToStr(Result)); end; function DoConfigOverride: Boolean; var i: Integer; begin if ConfigOverride = coUndefined then begin DebugMsg('DoConfigOverride', 'First call'); Result := False; ConfigOverride := coDontOverride; for i := 0 to ParamCount() do //use ParamCount/ParamStr to allow specifying /configoverride without any parameters if LowerCase(Copy(ParamStr(i),1,15)) = '/' + CONFIG_OVERRIDE_PARAM then begin Result := True; ConfigOverride := coOverride; break; end; end else if ConfigOverride = coOverride then Result := True else Result := False; DebugMsg('DoConfigOverride', BoolToStr(Result)); end; function GetExternalConfDir(Unused: String): String; begin if ExpandConstant('{param:' + CONFIG_OVERRIDE_PARAM + '|<>}') = '<>' then Result := ExpandConstant('{src}\') else Result := ExpandConstant('{param:' + CONFIG_OVERRIDE_PARAM + '|<>}\'); DebugMsg('GetExternalConfDir', Result); end; function CheckExternalConf(const pFile: String): Boolean; begin if not DoConfigOverride then //no config override Result := False else begin if FileExists(GetExternalConfDir('') + pFile) then //config file override only applies when that file exists Result := True else Result := False; end; DebugMsg('CheckExternalConf', pFile + ': ' + BoolToStr(Result)); end; procedure PrepareInterp(); var InterpFile,InterpContent,LuaBin: String; begin #ifdef PYTHON if IsComponentSelected('py') then begin StatusLabel(CustomMessage('SettingUpPyPika'),''); InterpFile := ExpandConstant('{app}\lib\pika\{#DIR_VER}\interpreters\pypika.interp'); DebugMsg('PrepareInterp','Writing interpreter file for pika-python: ' + InterpFile); #ifdef DEVEL #define PYTHON="python.exe" #else #define PYTHON="pythonw.exe" #endif InterpContent := 'python=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 + 'python3=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 + '/usr/bin/python=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 + '/usr/bin/python3=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 + ':Python:E::py::python:'#10; if not SaveStringToUTF8File(InterpFile,InterpContent,False) then begin DebugMsg('PrepareInterp','Problem writing the file. [' + InterpContent + ']'); SuppressibleMsgBox(CustomMessage('ErrorUpdatingPython') + ' (2)',mbInformation,mb_ok,IDOK); end; end; #endif #ifdef LUA if IsComponentSelected('lua') then begin InterpFile := ExpandConstant('{app}\lib\pika\{#DIR_VER}\interpreters\lua.interp'); DebugMsg('PrepareInterp','Writing interpreter file for lua: ' + InterpFile); if IsComponentSelected('pikaARM64') then begin LuaBin := 'lua5.1.exe' end else begin LuaBin := 'luajit.exe' end; InterpContent := 'lua=' + ExpandConstant('{app}\bin\') + LuaBin + #10 + 'luajit=' + ExpandConstant('{app}\bin\') + LuaBin + #10 + '/usr/bin/luajit=' + ExpandConstant('{app}\bin\') + LuaBin + #10 + '/usr/bin/lua=' + ExpandConstant('{app}\bin\') + LuaBin + #10 + ':Lua:E::lua::' + LuaBin + ':'#10; if not SaveStringToUTF8File(InterpFile,InterpContent,False) then begin DebugMsg('PrepareInterp','Problem writing the file. [' + InterpContent + ']'); SuppressibleMsgBox(CustomMessage('ErrorUpdatingPython') + ' (2)',mbInformation,mb_ok,IDOK); end; end; #endif // not optional // !!! use comma for binfmt delimiter and full Windows path in interpreter field of binfmt begin InterpFile := ExpandConstant('{app}\lib\pika\{#DIR_VER}\interpreters\pika-script-fu-interpreter.interp'); DebugMsg('PrepareInterp','Writing interpreter file for pika-script-fu-interpreter: ' + InterpFile); InterpContent := 'pika-script-fu-interpreter=' + ExpandConstant('{app}\bin\pika-script-fu-interpreter-3.0.exe') + #10 + 'pika-script-fu-interpreter-3.0=' + ExpandConstant('{app}\bin\pika-script-fu-interpreter-3.0.exe') + #10 + '/usr/bin/pika-script-fu-interpreter=' + ExpandConstant('{app}\bin\pika-script-fu-interpreter-3.0.exe') + #10 + ',ScriptFu,E,,scm,,' + ExpandConstant('{app}\bin\pika-script-fu-interpreter-3.0.exe') + ','#10; if not SaveStringToUTF8File(InterpFile,InterpContent,False) then begin DebugMsg('PrepareInterp','Problem writing the file. [' + InterpContent + ']'); SuppressibleMsgBox(CustomMessage('ErrorUpdatingScriptFu') + ' (2)',mbInformation,mb_ok,IDOK); end; end; end; procedure PreparePikaEnvironment(); var EnvFile,Env: String; begin StatusLabel(CustomMessage('SettingUpEnvironment'),''); //set PATH to be used by plug-ins EnvFile := ExpandConstant('{app}\lib\pika\{#DIR_VER}\environ\default.env'); DebugMsg('PreparePikaEnvironment','Setting environment in ' + EnvFile); Env := #10'PATH=${pika_installation_dir}\bin'; if IsComponentSelected('pika32on64') then begin Env := Env + ';${pika_installation_dir}\32\bin' + #10; end else begin Env := Env + #10; end; DebugMsg('PreparePikaEnvironment','Appending ' + Env); if not SaveStringToUTF8File(EnvFile,Env,True) then begin DebugMsg('PreparePikaEnvironment','Problem appending'); SuppressibleMsgBox(FmtMessage(CustomMessage('ErrorChangingEnviron'),[EnvFile]),mbInformation,mb_ok,IDOK); end; //workaround for high-DPI awareness of Python plug-ins if IsComponentSelected('py') then begin EnvFile := ExpandConstant('{app}\lib\pika\{#DIR_VER}\environ\pypika.env'); DebugMsg('PreparePikaEnvironment','Setting environment in ' + EnvFile); Env := '__COMPAT_LAYER=HIGHDPIAWARE' + #10 if not SaveStringToUTF8File(EnvFile,Env,True) then begin DebugMsg('PreparePikaEnvironment','Problem appending'); SuppressibleMsgBox(FmtMessage(CustomMessage('ErrorChangingEnviron'),[EnvFile]),mbInformation,mb_ok,IDOK); end; end; // Disable check-update when run with specific option if ExpandConstant('{param:disablecheckupdate|false}') = 'true' then begin EnvFile := ExpandConstant('{app}\share\pika\{#DIR_VER}\pika-release'); DebugMsg('DisableCheckUpdate','Disabling check-update in ' + EnvFile); Env := 'check-update=false' if not SaveStringToUTF8File(EnvFile,Env,True) then begin DebugMsg('PreparePikaEnvironment','Problem appending'); SuppressibleMsgBox(FmtMessage(CustomMessage('ErrorChangingEnviron'),[EnvFile]),mbInformation,mb_ok,IDOK); end; end; end; procedure CleanUpCustomWelcome(); begin WizardForm.NextButton.Visible := True; btnInstall.Visible := False; btnCustomize.Visible := False; WizardForm.Bevel.Visible := True; WelcomeBitmapBottom.Visible := False; end; procedure InstallOnClick(Sender: TObject); begin DebugMsg('Install mode','Simple'); InstallMode := imSimple; CleanUpCustomWelcome(); WizardForm.NextButton.OnClick(TNewButton(Sender).Parent); end; procedure CustomizeOnClick(Sender: TObject); begin DebugMsg('Install mode','Custom'); InstallMode := imCustom; CleanUpCustomWelcome(); WizardForm.NextButton.OnClick(TNewButton(Sender).Parent); end; function GetButtonWidth(const Texts: TArrayOfString; const Minimum: Integer): Integer; var MeasureLabel: TNewStaticText; i: Integer; begin MeasureLabel := TNewStaticText.Create(WizardForm); with MeasureLabel do begin Parent := WizardForm; Left := 0; Top := 0; AutoSize := True; end; Result := Minimum; for i := 0 to GetArrayLength(Texts) - 1 do begin MeasureLabel.Caption := Texts[i]; if (MeasureLabel.Width + ScaleX(16)) > Result then Result := (MeasureLabel.Width + ScaleX(16)); end; MeasureLabel.Free; end; procedure InitCustomPages(); var i,ButtonWidth: Integer; ButtonText: TArrayOfString; MeasureLabel: TNewStaticText; //lblInfo: TNewStaticText; begin DebugMsg('InitCustomPages','wpLicense'); btnInstall := TNewButton.Create(WizardForm); with btnInstall do begin Parent := WizardForm; Width := WizardForm.NextButton.Width; Height := WizardForm.NextButton.Height; Left := WizardForm.NextButton.Left; Top := WizardForm.NextButton.Top; Caption := CustomMessage('Install'); Default := True; Visible := False; OnClick := @InstallOnClick; end; //used to measure text width MeasureLabel := TNewStaticText.Create(WizardForm); with MeasureLabel do begin Parent := WizardForm; Left := 0; Top := 0; AutoSize := True; Caption := CustomMessage('Customize'); end; btnCustomize := TNewButton.Create(WizardForm); with btnCustomize do begin Parent := WizardForm; Width := WizardForm.NextButton.Width; if Width < (MeasureLabel.Width + ScaleX(8)) then Width := MeasureLabel.Width + ScaleX(8); Height := WizardForm.NextButton.Height; Left := WizardForm.ClientWidth - (WizardForm.CancelButton.Left + WizardForm.CancelButton.Width); //Left := WizardForm.BackButton.Left; Top := WizardForm.NextButton.Top; Visible := False; Caption := CustomMessage('Customize'); OnClick := @CustomizeOnClick; end; MeasureLabel.Free; end; procedure SelectComponentsFaceLift(); var pnlDescription: TPanel; lblDescription: TNewStaticText; begin DebugMsg('SelectComponentsFaceLift',''); if WizardForm.ComponentsList.Width = WizardForm.SelectComponentsPage.Width then WizardForm.ComponentsList.Width := Round(WizardForm.ComponentsList.Width * 0.6) else exit; DebugMsg('SelectComponentsFaceLift','2'); WizardForm.ComponentsList.OnClick := @ComponentsListOnClick; lblDescription := TNewStaticText.Create(WizardForm.ComponentsList.Parent) with lblDescription do begin Left := WizardForm.ComponentsList.Left + WizardForm.ComponentsList.Width + ScaleX(16); Top := WizardForm.ComponentsList.Top; AutoSize := True; Caption := CustomMessage('ComponentsDescription'); end; pnlDescription := TPanel.Create(WizardForm.ComponentsList.Parent); with pnlDescription do begin Parent := WizardForm.ComponentsList.Parent; Left := WizardForm.ComponentsList.Left + WizardForm.ComponentsList.Width + ScaleX(8); Width := WizardForm.TypesCombo.Width - WizardForm.ComponentsList.Width - ScaleX(8); BevelOuter := bvLowered; BevelInner := bvRaised; Top := WizardForm.ComponentsList.Top + Round(lblDescription.Height * 0.4); Height := WizardForm.ComponentsList.Height - Round(lblDescription.Height * 0.4); end; lblDescription.Parent := WizardForm.ComponentsList.Parent; //place lblDescription above pnlDescription lblComponentDescription := TNewStaticText.Create(pnlDescription); with lblComponentDescription do begin Parent := pnlDescription; Left := ScaleX(8); WordWrap := True; AutoSize := False; Width := Parent.Width - ScaleX(16); Height := Parent.Height - ScaleY(20); Top := ScaleY(12); end; end; procedure ReadyFaceLift(); var rtfNewReadyMemo: TRichEditViewer; begin DebugMsg('ReadyFaceLift',''); WizardForm.ReadyMemo.Visible := False; rtfNewReadyMemo := TRichEditViewer.Create(WizardForm.ReadyMemo.Parent); with rtfNewReadyMemo do begin Parent := WizardForm.ReadyMemo.Parent; Scrollbars := ssVertical; Color := WizardForm.Color; UseRichEdit := True; RTFText := ReadyMemoRichText; ReadOnly := True; Left := WizardForm.ReadyMemo.Left; Top := WizardForm.ReadyMemo.Top; Width := WizardForm.ReadyMemo.Width; Height := WizardForm.ReadyMemo.Height; Visible := True; end; end; procedure lblURL_OnClick(Sender: TObject); var ErrorCode: Integer; begin ShellExecAsOriginalUser('',PIKA_URL,'','',SW_SHOW,ewNoWait,ErrorCode); end; function MeasureLabel(const pText: String): Integer; //WordWrap + AutoSize works better with TNewStaticText than with TLabel, var lblMeasure: TNewStaticText; //abuse this begin lblMeasure := TNewStaticText.Create(WizardForm.InstallingPage); with lblMeasure do begin Parent := WizardForm.InstallingPage; AutoSize := True; WordWrap := True; Width := Parent.ClientWidth; Caption := pText; Result := Height; end; lblMeasure.Free; end; procedure InstallingFaceLift(); var lblMessage1,lblURL,lblMessage2: TLabel; //TNewStaticText doesn't support alignment begin with WizardForm.ProgressGauge do begin Height := ScaleY(16); Top := WizardForm.InstallingPage.ClientHeight - Top - Height; WizardForm.StatusLabel.Top := Top - WizardForm.FilenameLabel.Height - ScaleY(4); WizardForm.FilenameLabel.Top := Top + Height + ScaleY(4); end; lblMessage1 := TLabel.Create(WizardForm.InstallingPage); with lblMessage1 do begin Parent := WizardForm.InstallingPage; Alignment := taCenter; WordWrap := True; AutoSize := False; Width := WizardForm.InstallingPage.ClientWidth; Height := MeasureLabel(CustomMessage('Billboard1')); Caption := CustomMessage('Billboard1'); end; lblURL := TLabel.Create(WizardForm.InstallingPage); with lblURL do begin Parent := WizardForm.InstallingPage; AutoSize := True; WordWrap := False; Font.Color := GetSysColor(COLOR_HOTLIGHT); Font.Style := [fsUnderline]; Font.Size := 12; Cursor := crHand; OnClick := @lblURL_OnClick; Caption := PIKA_URL; Left := Integer(WizardForm.InstallingPage.ClientWidth / 2 - Width / 2); end; lblMessage2 := TLabel.Create(WizardForm.InstallingPage); with lblMessage2 do begin Parent := WizardForm.InstallingPage; Alignment := taCenter; WordWrap := True; AutoSize := False; Width := WizardForm.InstallingPage.ClientWidth; Height := MeasureLabel(CustomMessage('Billboard2')); Caption := CustomMessage('Billboard2'); end; lblMessage1.Top := Integer(WizardForm.StatusLabel.Top / 2 - (lblMessage1.Height + ScaleY(4) + lblURL.Height + ScaleY(4) + lblMessage2.Height) / 2); lblURL.Top := lblMessage1.Top + lblMessage1.Height + ScaleY(4); lblMessage2.Top := lblURL.Top + lblURL.Height + ScaleY(4); end; procedure ComponentsListOnClick(pSender: TObject); var i,j: Integer; Components: TArrayOfString; ComponentDesc: String; begin DebugMsg('ComponentsListOnClick',''); Components := ['Pika','Deps','Debug','Translations','MyPaint','Python','Ghostscript','Lua','Pika32']; ComponentDesc := ''; for i := 0 to TNewCheckListBox(pSender).Items.Count - 1 do if TNewCheckListBox(pSender).Selected[i] then begin for j := 0 to Length(Components) - 1 do begin if TNewCheckListBox(pSender).Items.Strings[i] = CustomMessage('Components' + Components[j]) then ComponentDesc := CustomMessage('Components' + Components[j] + 'Description'); end; if ComponentDesc <> '' then break; end; lblComponentDescription.Caption := ComponentDesc; end; function CopyW(const S: String; const Start, Len: Integer): String; //work-around for unicode-related bug in Copy begin Result := Copy(S, Start, Len); end; function Unicode2RTF(const pIn: String): String; //convert to RTF-compatible unicode var i: Integer; c: SmallInt; begin Result := ''; for i := 1 to Length(pIn) do if Ord(pIn[i]) <= 127 then begin Result := Result + pIn[i]; end else begin c := Ord(pIn[i]); //code points above 7FFF must be expressed as negative numbers Result := Result + '\u' + IntToStr(c) + '?'; end; end; function ParseReadyMemoText(pSpaces,pText: String): String; var sTemp: String; begin sTemp := CopyW(pText,Pos(#10,pText)+1,Length(pText)); sTemp := Replace('{','\{',sTemp); sTemp := Replace('\','\\',sTemp); sTemp := Replace(#13#10,RTFpara,sTemp); sTemp := Replace(pSpaces,'',sTemp); sTemp := '\b ' + CopyW(pText,1,Pos(#13,pText)-1) + '\par\sb0' + '\li284\b0 ' + sTemp + '\par \pard'; Result := Unicode2RTF(sTemp); end; function UpdateReadyMemo(pSpace, pNewLine, pMemoUserInfo, pMemoDirInfo, pMemoTypeInfo, pMemoComponentsInfo, pMemoGroupInfo, pMemoTasksInfo: String): String; var sText: String; bShowAssoc: Boolean; i,j: Integer; begin DebugMsg('UpdateReadyMemo',''); (* Prepare the text for new Ready Memo *) sText := RTFHeader; if pMemoDirInfo <> '' then sText := sText + ParseReadyMemoText(pSpace,pMemoDirInfo) + '\sb100'; sText := sText + ParseReadyMemoText(pSpace,pMemoTypeInfo); sText := sText + '\sb100' + ParseReadyMemoText(pSpace,pMemoComponentsInfo); If pMemoTasksInfo<>'' then sText := sText + '\sb100' + ParseReadyMemoText(pSpace,pMemoTasksInfo); ReadyMemoRichText := Copy(sText,1,Length(sText)-6) + '}'; Result := 'If you see this, something went wrong'; end; procedure UpdateWizardImages(); var NewBitmap1,NewBitmap2: TFileStream; begin WelcomeBitmapBottom := TBitmapImage.Create(WizardForm); with WelcomeBitmapBottom do begin Left := 0; Top := 0; Parent := WizardForm; Width := WizardForm.ClientWidth; Height := WizardForm.ClientHeight; Stretch := True; end; DebugMsg('UpdateWizardImages','Height: ' + IntToStr(WizardForm.WizardBitmapImage.Height)); if WizardForm.WizardBitmapImage.Height < 386 then //use smaller image when not using Large Fonts begin try NewBitmap1 := TFileStream.Create(ExpandConstant('{tmp}\installsplash_small.bmp'),fmOpenRead); WizardForm.WizardBitmapImage.Bitmap.LoadFromStream(NewBitmap1); WelcomeBitmapBottom.Bitmap := WizardForm.WizardBitmapImage.Bitmap; try NewBitmap2 := TFileStream.Create(ExpandConstant('{tmp}\windows-installer-intro-small.bmp'),fmOpenRead); WizardForm.WizardBitmapImage2.Bitmap.LoadFromStream(NewBitmap2); except DebugMsg('UpdateWizardImages','Error loading image: ' + GetExceptionMessage); finally if NewBitmap2 <> nil then NewBitmap2.Free; end; except DebugMsg('UpdateWizardImages','Error loading image: ' + GetExceptionMessage); finally if NewBitmap1 <> nil then NewBitmap1.Free; end; end else begin try NewBitmap1 := TFileStream.Create(ExpandConstant('{tmp}\installsplash.bmp'),fmOpenRead); WizardForm.WizardBitmapImage.Bitmap.LoadFromStream(NewBitmap1); WelcomeBitmapBottom.Bitmap := WizardForm.WizardBitmapImage.Bitmap; except DebugMsg('UpdateWizardImages','Error loading image: ' + GetExceptionMessage); finally if NewBitmap1 <> nil then NewBitmap1.Free; end; end; WizardForm.WizardBitmapImage.Width := WizardForm.ClientWidth; WizardForm.WizardBitmapImage.Height := WizardForm.ClientHeight; end; procedure DoUninstall(const UninstStr, InstallDir: String; const pInfoLabel: TNewStaticText; var oResult: TRemoveOldPIKAResult); var InResult: TRemoveOldPIKAResult; ResultCode, i: Integer; begin InResult := oResult; DebugMsg('DoUninstall','Uninstall string: ' + UninstStr); //when installing to same directory, assume that restart is required by default ... if LowerCase(RemoveBackslashUnlessRoot(InstallDir)) = LowerCase(RemoveBackslashUnlessRoot(ExpandConstant('{app}'))) then oResult := rogRestartRequired else oResult := InResult; pInfoLabel.Caption := InstallDir; if not Exec('>',UninstStr,'',SW_SHOW,ewWaitUntilTerminated,ResultCode) then begin DebugMsg('DoUninstall','Exec('+UninstStr+') failed: ' + IntToStr(ResultCode)); if not DirExists(InstallDir) then //old install directory doesn't exist, assume it was deleted, and Registry info is orphaned begin DebugMsg('DoUninstall','Install directory doesn'#39't exist: ' + InstallDir + ', resuming install'); oResult := InResult end else begin oResult := rogUninstallFailed; end; exit; end; DebugMsg('DoUninstall','Exec succeeded, uninstaller result: ' + IntToStr(ResultCode)); //... unless the complete installation directory was removed on uninstall i := 0; while i < (UNINSTALL_MAX_WAIT_TIME / UNINSTALL_CHECK_TIME) do begin if not DirExists(ExpandConstant('{app}')) then begin DebugMsg('DoUninstall','Existing PIKA directory removed, restoring previous restart requirement'); oResult := InResult; //restore previous result break; end; DebugMsg('DoUninstall','Waiting for ' + ExpandConstant('{app}') + ' to disappear [' + IntToStr(i) + ']'); Sleep(UNINSTALL_CHECK_TIME); //it may take a few seconds for the uninstaller to remove the directory after it's exited Inc(i); end; end; function RemoveOldPIKAVersions(): TRemoveOldPIKAResult; var lblInfo1,lblInfo2: TNewStaticText; RootKey: Integer; OldPath, UninstallString, WhichStr: String; begin Result := rogContinue; lblInfo1 := TNewStaticText.Create(WizardForm.PreparingPage); with lblInfo1 do begin Parent := WizardForm.PreparingPage; Left := 0; Top := 0; AutoSize := True; WordWrap := True; Width := WizardForm.PreparingPage.ClientWidth; Caption := CustomMessage('RemovingOldVersion'); end; lblInfo2 := TNewStaticText.Create(WizardForm.PreparingPage); with lblInfo2 do begin Parent := WizardForm.PreparingPage; Left := 0; AutoSize := True; WordWrap := True; Width := WizardForm.PreparingPage.ClientWidth; Top := lblInfo1.Height + ScaleY(8); end; if ExpandConstant('{param:debugresume|0}') = '1' then Result := rogRestartRequired; //for testing if Is64BitInstallMode() then RootKey := HKLM32 else RootKey := HKLM; if RegValueExists(RootKey,'Software\Microsoft\Windows\CurrentVersion\Uninstall\WinGimp-2.0_is1', 'Inno Setup: App Path') then begin if RegQueryStringValue(RootKey,'Software\Microsoft\Windows\CurrentVersion\Uninstall\WinGimp-2.0_is1', 'Inno Setup: App Path',OldPath) then begin DebugMsg('RemoveOldPIKAVersions','Found legacy PIKA install, removing'); if RegValueExists(RootKey,'Software\Microsoft\Windows\CurrentVersion\Uninstall\WinGimp-2.0_is1', 'QuietUninstallString') then WhichStr := 'QuietUninstallString' else if RegValueExists(RootKey,'Software\Microsoft\Windows\CurrentVersion\Uninstall\WinGimp-2.0_is1', 'UninstallString') then WhichStr := 'UninstallString' else begin Result := rogCantUninstall; exit; end; if not RegQueryStringValue(RootKey,'Software\Microsoft\Windows\CurrentVersion\Uninstall\WinGimp-2.0_is1', WhichStr,UninstallString) then begin Result := rogCantUninstall; exit; end; if WhichStr = 'UninstallString' then UninstallString := UninstallString + ' /SILENT'; UninstallString := UninstallString + ' /NORESTART'; DoUninstall(UninstallString, OldPath, lblInfo2, Result); end; end; lblInfo1.Free; lblInfo2.Free; end; procedure InfoBeforeLikeLicense(); begin WizardForm.InfoBeforeClickLabel.Visible := False; WizardForm.InfoBeforeMemo.Height := WizardForm.InfoBeforeMemo.Height + WizardForm.InfoBeforeMemo.Top - WizardForm.InfoBeforeClickLabel.Top; WizardForm.InfoBeforeMemo.Top := WizardForm.InfoBeforeClickLabel.Top; end; procedure PrepareWelcomePage(); begin if not WizardSilent then begin WizardForm.NextButton.Visible := False; btnInstall.Visible := True; btnInstall.TabOrder := 1; btnCustomize.Visible := True; WizardForm.Bevel.Visible := False; WizardForm.WelcomeLabel1.Visible := False; WizardForm.WelcomeLabel2.Visible := False; WelcomeBitmapBottom.Visible := True; end; end; procedure CurPageChanged(pCurPageID: Integer); begin DebugMsg('CurPageChanged','ID: '+IntToStr(pCurPageID)); case pCurPageID of wpWelcome: PrepareWelcomePage(); wpInfoBefore: InfoBeforeLikeLicense(); wpSelectComponents: SelectComponentsFaceLift(); wpReady: ReadyFaceLift(); wpInstalling: InstallingFaceLift(); end; end; function ShouldSkipPage(pPageID: Integer): Boolean; begin DebugMsg('ShouldSkipPage','ID: '+IntToStr(pPageID)); Result := ((InstallMode = imSimple) or (InstallMode = imRebootContinue)) and (pPageID <> wpFinished); //skip all pages except for the finished one if using simple //install mode if Result then DebugMsg('ShouldSkipPage','Yes') else DebugMsg('ShouldSkipPage','No'); end; procedure RemoveDebugFilesFromDir(pDir: String; var pDirectories: TArrayOfString); var FindRec: TFindRec; begin DebugMsg('RemoveDebugFilesFromDir', pDir); WizardForm.FilenameLabel.Caption := pDir; if FindFirst(AddBackSlash(pDir) + '*', FindRec) then begin try repeat if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin if (Length(FindRec.Name) > 6) and (LowerCase(Copy(FindRec.Name, Length(FindRec.Name) - 5, 6)) = '.debug') then begin DebugMsg('RemoveDebugFilesFromDir', '> ' + FindRec.Name); DeleteFile(AddBackSlash(pDir) + FindRec.Name); end; end else begin if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin SetArrayLength(pDirectories, GetArrayLength(pDirectories) + 1); pDirectories[GetArrayLength(pDirectories) - 1] := AddBackSlash(pDir) + FindRec.Name; end; end; until not FindNext(FindRec); finally FindClose(FindRec); end; end; end; //remove .debug files from previous installs //there's no built-in way in Inno to recursively delete files with wildcard+extension procedure RemoveDebugFiles(); var Directories: TArrayOfString; Index: Integer; begin SetArrayLength(Directories, 1); Directories[0] := ExpandConstant('{app}'); Index := 0; WizardForm.StatusLabel.Caption := CustomMessage('RemovingOldFiles'); repeat RemoveDebugFilesFromDir(Directories[Index], Directories); Inc(Index); until Index = GetArrayLength(Directories); end; procedure CurStepChanged(pCurStep: TSetupStep); begin case pCurStep of ssInstall: begin RemoveDebugFiles(); AssociationsCleanup(); end; ssPostInstall: begin PrepareInterp(); PreparePikaEnvironment(); end; end; end; function PrepareToInstall(var pNeedsRestart: Boolean): String; var ChecksumBefore, ChecksumAfter: String; RemoveResult: TRemoveOldPIKAResult; begin ChecksumBefore := MakePendingFileRenameOperationsChecksum; RemoveResult := RemoveOldPIKAVersions; if RemoveResult = rogRestartRequired then //old version was uninstalled, but something was left behind, so to be safe a reboot begin //is enforced - this can only happen when reusing install directory DebugMsg('PrepareToInstall','RemoveOldPIKAVersions requires restart'); ChecksumAfter := MakePendingFileRenameOperationsChecksum; if (ChecksumBefore <> ChecksumAfter) or (ExpandConstant('{param:debugresume|0}') = '1') then begin //this check is most likely redundant, since the uninstaller will be added to pending rename operations CreateRunOnceEntry; pNeedsRestart := True; Result := CustomMessage('RebootRequiredFirst'); end; end else if RemoveResult = rogContinue then begin DebugMsg('PrepareToInstall','RemoveOldPIKAVersions finished successfully'); Result := ''; //old version was uninstalled successfully, nothing was left behind, so install can continue immediately end else if RemoveResult = rogUninstallFailed then begin DebugMsg('PrepareToInstall','RemoveOldPIKAVersions failed to uninstall old PIKA version'); Result := FmtMessage(CustomMessage('RemovingOldVersionFailed'),['{#VERSION}',ExpandConstant('{app}')]); end else if RemoveResult = rogCantUninstall then begin DebugMsg('PrepareToInstall','RemoveOldPIKAVersions failed to uninstall old PIKA version [1]'); Result := FmtMessage(CustomMessage('RemovingOldVersionCantUninstall'),['{#VERSION}',ExpandConstant('{app}')]); end else begin DebugMsg('PrepareToInstall','Internal error 11'); Result := FmtMessage(CustomMessage('InternalError'),['11']); //should never happen end; end; procedure InitializeWizard(); begin UpdateWizardImages(); InitCustomPages(); end; function BPPTooLowWarning(): Boolean; var hDC, bpp, pl: Integer; Message,Buttons: TArrayOfString; begin hDC := GetDC(0); pl := GetDeviceCaps(hDC, PLANES); bpp := GetDeviceCaps(hDC, BITSPIXEL); ReleaseDC(0,hDC); bpp := pl * bpp; if bpp < 32 then begin SetArrayLength(Message,1); SetArrayLength(Buttons,2); Message[0] := CustomMessage('Require32BPP'); Buttons[0] := CustomMessage('Require32BPPContinue'); Buttons[1] := CustomMessage('Require32BPPExit'); if (not WizardSilent) and (MessageWithURL(Message, CustomMessage('Require32BPPTitle'), Buttons, mbError, 2, 2) = 2) then Result := False else Result := True; end else Result := True; end; procedure Check32bitOverride; var i: Integer; old: String; begin Force32bitInstall := False; old := LowerCase(GetPreviousData('32bitMode','')); if old = 'true' then //ignore command line if previous install is already present Force32bitInstall := True else if old = 'false' then Force32bitInstall := False else for i := 0 to ParamCount do //not a bug (in script anyway) - ParamCount returns the index of last ParamStr element, not the actual count if ParamStr(i) = '/32' then begin Force32bitInstall := True; break; end; DebugMsg('Check32bitOverride',BoolToStr(Force32bitInstall) + '[' + old + ']'); end; function InitializeSetup(): Boolean; #if (Defined(DEVEL) && DEVEL != "") || Defined(DEVEL_WARNING) var Message,Buttons: TArrayOfString; #endif begin ConfigOverride := coUndefined; if not IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE) then begin SuppressibleMsgBox(CustomMessage('SSERequired'), mbCriticalError, MB_OK, 0); Result := false; exit; end; Check32bitOverride; Result := RestartSetupAfterReboot(); //resume install after reboot - skip all setting pages, and install directly if Result then Result := BPPTooLowWarning(); if not Result then //no need to do anything else exit; #if (Defined(DEVEL) && DEVEL != "") || Defined(DEVEL_WARNING) Explode(Message, CustomMessage('DevelopmentWarning'), #13#10); SetArrayLength(Buttons,2); Buttons[0] := CustomMessage('DevelopmentButtonContinue'); Buttons[1] := CustomMessage('DevelopmentButtonExit'); if (not WizardSilent) and (MessageWithURL(Message, CustomMessage('DevelopmentWarningTitle'), Buttons, mbError, 2, 2) = 2) then begin Result := False; Exit; end; #endif try ExtractTemporaryFile('windows-installer-intro-small.bmp'); ExtractTemporaryFile('installsplash.bmp'); ExtractTemporaryFile('installsplash_small.bmp'); except DebugMsg('InitializeSetup','Error extracting temporary file: ' + GetExceptionMessage); MsgBox(CustomMessage('ErrorExtractingTemp') + #13#13 + GetExceptionMessage,mbError,MB_OK); Result := False; exit; end; //if InstallMode <> imRebootContinue then // SuppressibleMsgBox(CustomMessage('UninstallWarning'),mbError,MB_OK,IDOK); end; procedure RegisterPreviousData(PreviousDataKey: Integer); begin if Is64BitInstallMode() then SetPreviousData(PreviousDataKey,'32BitMode',BoolToStr(Force32bitInstall)); end; procedure SaveToUninstInf(const pText: AnsiString); var sUnInf: String; sOldContent: String; begin sUnInf := ExpandConstant('{app}\uninst\uninst.inf'); if not FileExists(sUnInf) then //save small header SaveStringToUTF8File(sUnInf,#$feff+'#Additional uninstall tasks'#13#10+ //#$feff BOM is required for LoadStringsFromFile '#This file uses UTF-8 encoding'#13#10+ '#'#13#10+ '#Empty lines and lines beginning with # are ignored'#13#10+ '#'#13#10+ '#Add uninstallers for PIKA add-ons that should be removed together with PIKA like this:'#13#10+ '#Run://'#13#10+ '#'#13#10+ '#The file is parsed in reverse order' + #13#10 + '' + #13#10 //needs '' in front, otherwise preprocessor complains ,False) else begin LoadStringFromUTF8File(sUnInf,sOldContent); if Pos(#13#10+pText+#13#10,sOldContent) > 0 then //don't write duplicate lines exit; end; SaveStringToUTF8File(sUnInf,pText+#13#10,True); end; #include "rebootcontinue.isi" #include "uninst.isi" #expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")