├── .gitignore ├── Build_Groups_Panel_Example.jpg ├── LICENSE ├── Languages ├── BrazilianPortuguese.isl ├── Catalan.isl ├── Default.LICENSE ├── Default.isl ├── French.isl ├── German.isl ├── Italian.isl └── Spanish.isl ├── README.md ├── Scripts └── Setup.Preprocessor.ClearFiles.bat ├── Setup.png ├── Source ├── IO.Utils.inc ├── RADStudio.Build.inc ├── RADStudio.Project.inc ├── RADStudio.inc ├── Setup.Main.inc ├── Setup.Pages.inc ├── Setup.Style.inc ├── Setup.Utils.inc └── String.Utils.inc ├── Style ├── Amakrits.vsf ├── AmethystKamri.vsf ├── AquaGraphite.vsf ├── AquaLightSlate.vsf ├── Auric.vsf ├── BlueGraphite.vsf ├── Carbon.vsf ├── CharcoalDarkSlate.vsf ├── CobaltXEMedia.vsf ├── CyanDusk.vsf ├── CyanNight.vsf ├── EmeraldLightSlate.vsf ├── Glossy.vsf ├── Glow.vsf ├── GoldenGraphite.vsf ├── GreenGraphite.vsf ├── IcebergClassico.vsf ├── LavenderClassico.vsf ├── Light.vsf ├── LightGreen.vsf ├── Luna.vsf ├── OnyxBlue.vsf ├── OrangeGraphite.vsf ├── Pink.vsf ├── RubyGraphite.vsf ├── SapphireKamri.vsf ├── Sky.vsf ├── SlateClassico.vsf ├── SmokeyQuartzKamri.vsf ├── TabletDark.vsf ├── TurquoiseGray.vsf ├── Windows10.vsf ├── Windows10Blue.vsf ├── Windows10Dark.vsf ├── Windows11.Dark.vsf ├── YellowGraphite.vsf ├── khaki.vsf ├── lilac.vsf ├── sepia.vsf └── vcl-styles-plugins │ └── README.md └── Template ├── Setup.iss ├── WizClassicImage.bmp └── WizClassicSmallImage.bmp /.gitignore: -------------------------------------------------------------------------------- 1 | # Uncomment these types if you want even more clean repository. But be careful. 2 | # It can make harm to an existing project source. Read explanations below. 3 | # 4 | # Resource files are binaries containing manifest, project icon and version info. 5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. 6 | #*.res 7 | # 8 | # Type library file (binary). In old Delphi versions it should be stored. 9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored. 10 | #*.tlb 11 | # 12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7. 13 | # Uncomment this if you are not using diagrams or use newer Delphi version. 14 | #*.ddp 15 | # 16 | # Visual LiveBindings file. Added in Delphi XE2. 17 | # Uncomment this if you are not using LiveBindings Designer. 18 | #*.vlb 19 | # 20 | # Deployment Manager configuration file for your project. Added in Delphi XE2. 21 | # Uncomment this if it is not mobile development and you do not use remote debug feature. 22 | #*.deployproj 23 | # 24 | # C++ object files produced when C/C++ Output file generation is configured. 25 | # Uncomment this if you are not using external objects (zlib library for example). 26 | #*.obj 27 | # 28 | 29 | # Default Delphi compiler directories 30 | # Content of this directories are generated with each Compile/Construct of a project. 31 | # Most of the time, files here have not there place in a code repository. 32 | #Win32/ 33 | #Win64/ 34 | #OSX64/ 35 | #OSXARM64/ 36 | #Android/ 37 | #Android64/ 38 | #iOSDevice64/ 39 | #Linux64/ 40 | 41 | # Delphi compiler-generated binaries (safe to delete) 42 | *.exe 43 | *.dll 44 | *.bpl 45 | *.bpi 46 | *.dcp 47 | *.so 48 | *.apk 49 | *.drc 50 | *.map 51 | *.dres 52 | *.rsm 53 | *.tds 54 | *.dcu 55 | *.lib 56 | *.a 57 | *.o 58 | *.ocx 59 | 60 | # Delphi autogenerated files (duplicated info) 61 | *.cfg 62 | *.hpp 63 | *Resource.rc 64 | 65 | # Delphi local files (user-specific info) 66 | *.local 67 | *.identcache 68 | *.projdata 69 | *.tvsconfig 70 | *.dsk 71 | 72 | # Delphi history and backups 73 | __history/ 74 | __recovery/ 75 | *.~* 76 | 77 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi) 78 | *.stat 79 | 80 | # Boss dependency manager vendor folder https://github.com/HashLoad/boss 81 | modules/ 82 | -------------------------------------------------------------------------------- /Build_Groups_Panel_Example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Build_Groups_Panel_Example.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024-2025 Ethea S.r.l. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Languages/BrazilianPortuguese.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Instalação concluída 3 | FinishedLabel=A instalação do [name] no seu computador foi concluída. 4 | SetupWindowTitle=Instalador do %1 5 | WelcomeLabel1=Instalador do [name] 6 | WelcomeLabel2=A biblioteca [name/ver] será instalado no seu computador. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=Microsoft .NET Framework 3.5 SP1 não foi encontrado. 10 | DotNet45NotFound=Microsoft .NET Framework 4.5 não foi encontrado. 11 | RADStudioBuildBuildingFor=Compilando para %1 - %2... 12 | RADStudioBuildErrorBuilding=Erro ao compilar para %1 (code %2). 13 | RADStudioBuildErrorCantFoundRSVars=Não foi possível encontrar o arquivo rsvars "%1" do %2. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=O %1 não suporta compilação via command line. Você deve fazer a instalação da biblioteca manualmente. 15 | RADStudioProjectErrorParsingGroupProject=Erro ao analisar o projeto "%1" (código %2, linha %3, posição %4, mensagem "%5"). 16 | RADStudioProjectErrorParsingProject=Erro ao analisar o projeto "%1" (código %2, linha %3, posição %4, mensagem "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Erro ao analisar o projeto "%1" (texto %2, mensagem "Personalidade desconhecida"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Erro ao analisar o group project "%1" (mensagem "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Erro ao analisar o projeto "%1" (mensagem "%2"). 20 | RADStudioUnknownVersionName=Nome desconhecido 21 | SetupMainCouldNotDetectProjectBplOutputFileName=Não foi possível detectar o nome de arquivo Bpl gerado no projeto "%1" do %2. 22 | SetupMainCouldNotUninstallDetectedVersion=Não foi possível desinstalar outras versões do %1 detectadas no seu sistema. 23 | SetupMainCouldNotUninstallPackages=Não foi possível desinstalar os packages. 24 | SetupMainErrorFailedToGetGroupProjects=Falha ao tentar detectar os arquivos group projects. 25 | SetupMainErrorNoRADStudioVersionAvailable=Nenhuma versão do RAD Studio está disponível no seu sistema para a instalação. 26 | SetupMainFailedToInstallPackage=Falha ao instalar o package "%1" no %2 (código %3) 27 | SetupMainFailedToUninstallPackage=Falha ao desinstalar o package "%1" no %2 (código %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Feche o RAD Studio antes de tentar instalar. Se você já fechou, aguarde um pouco antes de tentar novamente. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Instalação bem sucedida. Por favor, reabra o seu RAD Studio. 30 | SetupMainInstallingPackages=Instalando os packages... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Revertendo a instalação dos packages... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=Desinstalação abortada! Antes de desinstalar, feche todas as instâncias do seu RAD Studio. 33 | SetupMainUninstallingDetectedVersion=Desinstalando outras versões... 34 | SetupMainUninstallingFromGetIt=Desinstalando pelo GetIt... 35 | SetupMainUninstallingPackages=Desinstalando packages... 36 | SetupOpenSamplesFolder=Abrir a pasta de demos 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=Você não escolheu nenhuma versão do RAD Studio e se continuar, a instalação apenas fará a extração dos arquivos. Você deseja continuar? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=Precisa ser aberto primeiro 39 | SetupPagesRADStudioVersionsChoiceMessage=Selecione as versões do RAD Studio que você deseja instalar o %1 40 | SetupPagesRADStudioVersionsChoiceTitle=Selecione o RAD Studio 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Suporte extraoficial 42 | SetupUtilsPleaseReportThiIssue=%n%nPor favor, reporte este problema. 43 | SetupViewOnlineDocumentation=Ver a documentação online 44 | -------------------------------------------------------------------------------- /Languages/Catalan.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Completant la instal·lació de [name] 3 | FinishedLabel=La instal·lació ha finalitzat l'instal·lació de [name] al seu ordinador. 4 | SetupWindowTitle=Instal·lació de %1 5 | WelcomeLabel1=Instal·lació de [name] 6 | WelcomeLabel2=Aquest programa instal·larà la biblioteca [name/ver] al seu ordinador. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=No s'ha trobat Microsoft .NET Framework 3.5 SP1. 10 | DotNet45NotFound=No s'ha trobat Microsoft .NET Framework 4.5. 11 | RADStudioBuildBuildingFor=Generant per %1 - %2... 12 | RADStudioBuildErrorBuilding=Error de compilació per %1 (codi %2). 13 | RADStudioBuildErrorCantFoundRSVars=No es pot trobar el fitxer rsvars "%1" de %2. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=%1 no admet la compilació des de línia de comandaments. Cal instal·lar manualment la biblioteca. 15 | RADStudioProjectErrorParsingGroupProject=Error en analitzar el projecte de grup "%1" (codi %2, línia %3, posició %4, missatge "%5"). 16 | RADStudioProjectErrorParsingProject=Error en analitzar el projecte "%1" (codi %2, línia %3, posició %4, missatge "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Error en analitzar el projecte "%1" (text %2, missatge "Personalitat desconeguda"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Error inesperat en analitzar el projecte de grup "%1" (missatge "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Error inesperat en analitzar el projecte "%1" (missatge "%2"). 20 | RADStudioUnknownVersionName=Nom desconegut 21 | SetupMainCouldNotDetectProjectBplOutputFileName=No s'ha pogut detectar el nom del fitxer Bpl generat pel projecte "%1" de %2. 22 | SetupMainCouldNotUninstallDetectedVersion=No s'han pogut desinstal·lar altres versions de %1 detectades al sistema. 23 | SetupMainCouldNotUninstallPackages=No s'han pogut desinstal·lar els Packages. 24 | SetupMainErrorFailedToGetGroupProjects=No s'han pogut obtenir els fitxers de projectes de grup. 25 | SetupMainErrorNoRADStudioVersionAvailable=No hi ha cap versió de RAD Studio disponible al sistema per a la instal·lació. 26 | SetupMainFailedToInstallPackage=No s'ha pogut instal·lar el Package "%1" a %2 (codi %3) 27 | SetupMainFailedToUninstallPackage=No s'ha pogut desinstal·lar el Package "%1" a %2 (codi %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Si us plau, tanqui RAD Studio abans d'intentar la instal·lació. Si ja l'ha tancat, esperi una mica i torni-ho a intentar. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Instal·lació completada. Reiniciï RAD Studio. 30 | SetupMainInstallingPackages=Instal·lant Packages... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Revertint la instal·lació de Packages després d'un error... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=Desinstal·lació cancel·lada! Tanqui totes les instàncies de RAD Studio abans de desinstal·lar. 33 | SetupMainUninstallingDetectedVersion=Desinstal·lant altres versions... 34 | SetupMainUninstallingFromGetIt=Desinstal·lant des de GetIt... 35 | SetupMainUninstallingPackages=Desinstal·lant Packages... 36 | SetupOpenSamplesFolder=Obre la carpeta d'exemples 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=No ha escollit cap versió de RAD Studio i, si continua, només s'extrauran els fitxers. Vol continuar? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=Cal obrir-lo primer 39 | SetupPagesRADStudioVersionsChoiceMessage=Seleccioni les versions de RAD Studio per a les quals vol instal·lar %1 40 | SetupPagesRADStudioVersionsChoiceTitle=Trieu RAD Studio 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Suport no oficial 42 | SetupUtilsPleaseReportThiIssue=%n%nSi us plau, informi d'aquest problema. 43 | SetupViewOnlineDocumentation=Veure documentació en línia -------------------------------------------------------------------------------- /Languages/Default.LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2024 Skia4Delphi Project 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /Languages/Default.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Completing [name] Setup 3 | FinishedLabel=Setup has finished installing [name] on your computer. 4 | SetupWindowTitle=%1 Setup 5 | WelcomeLabel1=[name] Setup 6 | WelcomeLabel2=This will install the library [name/ver] on your computer. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=Microsoft .NET Framework 3.5 SP1 was not found. 10 | DotNet45NotFound=Microsoft .NET Framework 4.5 was not found. 11 | RADStudioBuildBuildingFor=Building for %1 - %2... 12 | RADStudioBuildErrorBuilding=Error compiling for %1 (code %2). 13 | RADStudioBuildErrorCantFoundRSVars=Can't found the rsvars file "%1" of %2. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=The %1 does not support command line compilation. You have to install the library manually. 15 | RADStudioProjectErrorParsingGroupProject=Error parsing the project "%1" (code %2, line %3, position %4, message "%5"). 16 | RADStudioProjectErrorParsingProject=Error parsing the project "%1" (code %2, line %3, position %4, message "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Error parsing the project "%1" (text %2, message "Unknown personality"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Error parsing the group project "%1" (message "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Error parsing the project "%1" (message "%2"). 20 | RADStudioUnknownVersionName=Unknown name 21 | SetupMainCouldNotDetectProjectBplOutputFileName=Could not detect the filename of Bpl file, generated by the project "%1" of %2. 22 | SetupMainCouldNotUninstallDetectedVersion=Could not uninstall other versions of %1 detected in your system. 23 | SetupMainCouldNotUninstallPackages=Could not uninstall the packages. 24 | SetupMainErrorFailedToGetGroupProjects=Failed to get group projects files. 25 | SetupMainErrorNoRADStudioVersionAvailable=No version of RAD Studio available in your system for installation. 26 | SetupMainFailedToInstallPackage=Failed to install the package "%1" in %2 (code %3) 27 | SetupMainFailedToUninstallPackage=Failed to uninstall the package "%1" in %2 (code %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Please close RAD Studio before attempting to install. If you have already closed, please wait a while before trying again. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Installation succesfully. Please restart your RAD Studio. 30 | SetupMainInstallingPackages=Installing packages... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Reverting package installation... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=Uninstall aborted! Before uninstall, close all instances of the RAD Studio. 33 | SetupMainUninstallingDetectedVersion=Uninstalling other versions... 34 | SetupMainUninstallingFromGetIt=Uninstalling from GetIt... 35 | SetupMainUninstallingPackages=Uninstalling packages... 36 | SetupOpenSamplesFolder=Open samples folder 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=You have not chosen any version of RAD Studio and if you proceed, the installation will only extract the files. Do you wish to continue? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=Need open it first 39 | SetupPagesRADStudioVersionsChoiceMessage=Check the RAD Studio versions do you want to install the %1 40 | SetupPagesRADStudioVersionsChoiceTitle=Choose RAD Studio 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Unofficial support 42 | SetupUtilsPleaseReportThiIssue=%n%nPlease, report this issue. 43 | SetupViewOnlineDocumentation=View online documentation 44 | -------------------------------------------------------------------------------- /Languages/French.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Finalisation de l'installation de [name] 3 | FinishedLabel=L'installation de [name] est terminée sur votre ordinateur. 4 | SetupWindowTitle=Installation de %1 5 | WelcomeLabel1=Installation de [name] 6 | WelcomeLabel2=Ce programme va installer la bibliothèque [name/ver] sur votre ordinateur. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=Microsoft .NET Framework 3.5 SP1 n'a pas été trouvé. 10 | DotNet45NotFound=Microsoft .NET Framework 4.5 n'a pas été trouvé. 11 | RADStudioBuildBuildingFor=Compilation pour %1 - %2... 12 | RADStudioBuildErrorBuilding=Erreur de compilation pour %1 (code %2). 13 | RADStudioBuildErrorCantFoundRSVars=Impossible de trouver le fichier rsvars "%1" de %2. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=%1 ne prend pas en charge la compilation en ligne de commande. Vous devez installer la bibliothèque manuellement. 15 | RADStudioProjectErrorParsingGroupProject=Erreur lors de l'analyse du projet de groupe "%1" (code %2, ligne %3, position %4, message "%5"). 16 | RADStudioProjectErrorParsingProject=Erreur lors de l'analyse du projet "%1" (code %2, ligne %3, position %4, message "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Erreur lors de l'analyse du projet "%1" (texte %2, message "Personnalité inconnue"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Erreur inattendue lors de l'analyse du projet de groupe "%1" (message "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Erreur inattendue lors de l'analyse du projet "%1" (message "%2"). 20 | RADStudioUnknownVersionName=Nom inconnu 21 | SetupMainCouldNotDetectProjectBplOutputFileName=Impossible de détecter le nom du fichier Bpl généré par le projet "%1" de %2. 22 | SetupMainCouldNotUninstallDetectedVersion=Impossible de désinstaller les autres versions de %1 détectées sur votre système. 23 | SetupMainCouldNotUninstallPackages=Impossible de désinstaller les packages. 24 | SetupMainErrorFailedToGetGroupProjects=Échec de récupération des fichiers de projets de groupe. 25 | SetupMainErrorNoRADStudioVersionAvailable=Aucune version de RAD Studio disponible sur votre système pour l'installation. 26 | SetupMainFailedToInstallPackage=Échec de l'installation du package "%1" dans %2 (code %3) 27 | SetupMainFailedToUninstallPackage=Échec de la désinstallation du package "%1" dans %2 (code %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Veuillez fermer RAD Studio avant de tenter l'installation. Si vous l'avez déjà fermé, veuillez patienter un moment avant de réessayer. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Installation terminée. Veuillez redémarrer RAD Studio. 30 | SetupMainInstallingPackages=Installation des packages... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Annulation de l'installation des packages après une erreur... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=Désinstallation annulée ! Fermez toutes les instances de RAD Studio avant de désinstaller. 33 | SetupMainUninstallingDetectedVersion=Désinstallation des autres versions... 34 | SetupMainUninstallingFromGetIt=Désinstallation depuis GetIt... 35 | SetupMainUninstallingPackages=Désinstallation des packages... 36 | SetupOpenSamplesFolder=Ouvrir le dossier des exemples 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=Vous n'avez sélectionné aucune version de RAD Studio et si vous continuez, seuls les fichiers seront extraits. Voulez-vous continuer ? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=Besoin de l'ouvrir d'abord 39 | SetupPagesRADStudioVersionsChoiceMessage=Sélectionnez les versions de RAD Studio pour lesquelles vous voulez installer %1 40 | SetupPagesRADStudioVersionsChoiceTitle=Choisir RAD Studio 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Support non officiel 42 | SetupUtilsPleaseReportThiIssue=%n%nVeuillez signaler ce problème. 43 | SetupViewOnlineDocumentation=Voir la documentation en ligne -------------------------------------------------------------------------------- /Languages/German.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Abschluss der Installation von [name] 3 | FinishedLabel=Die Installation von [name] wurde auf Ihrem Computer abgeschlossen. 4 | SetupWindowTitle=Installation von %1 5 | WelcomeLabel1=Installation von [name] 6 | WelcomeLabel2=Dieses Programm wird die Bibliothek [name/ver] auf Ihrem Computer installieren. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=Microsoft .NET Framework 3.5 SP1 wurde nicht gefunden. 10 | DotNet45NotFound=Microsoft .NET Framework 4.5 wurde nicht gefunden. 11 | RADStudioBuildBuildingFor=Erstellen für %1 - %2... 12 | RADStudioBuildErrorBuilding=Fehler beim Kompilieren für %1 (Code %2). 13 | RADStudioBuildErrorCantFoundRSVars=Die rsvars-Datei "%1" von %2 wurde nicht gefunden. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=%1 unterstützt keine Befehlszeilenkompilierung. Sie müssen die Bibliothek manuell installieren. 15 | RADStudioProjectErrorParsingGroupProject=Fehler beim Analysieren des Gruppenprojekts "%1" (Code %2, Zeile %3, Position %4, Nachricht "%5"). 16 | RADStudioProjectErrorParsingProject=Fehler beim Analysieren des Projekts "%1" (Code %2, Zeile %3, Position %4, Nachricht "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Fehler beim Analysieren des Projekts "%1" (Text %2, Nachricht "Unbekannte Persönlichkeit"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Unerwarteter Fehler beim Analysieren des Gruppenprojekts "%1" (Nachricht "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Unerwarteter Fehler beim Analysieren des Projekts "%1" (Nachricht "%2"). 20 | RADStudioUnknownVersionName=Unbekannter Name 21 | SetupMainCouldNotDetectProjectBplOutputFileName=Der Dateiname der Bpl-Datei, die vom Projekt "%1" von %2 generiert wurde, konnte nicht erkannt werden. 22 | SetupMainCouldNotUninstallDetectedVersion=Andere Versionen von %1, die in Ihrem System erkannt wurden, konnten nicht deinstalliert werden. 23 | SetupMainCouldNotUninstallPackages=Die Package konnten nicht deinstalliert werden. 24 | SetupMainErrorFailedToGetGroupProjects=Fehler beim Abrufen der Gruppenprojekt-Dateien. 25 | SetupMainErrorNoRADStudioVersionAvailable=Keine RAD Studio-Version in Ihrem System für die Installation verfügbar. 26 | SetupMainFailedToInstallPackage=Fehler beim Installieren des Packages "%1" in %2 (Code %3) 27 | SetupMainFailedToUninstallPackage=Fehler beim Deinstallieren des Packages "%1" in %2 (Code %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Bitte schließen Sie RAD Studio, bevor Sie die Installation versuchen. Wenn Sie es bereits geschlossen haben, warten Sie einen Moment und versuchen Sie es erneut. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Installation abgeschlossen. Bitte starten Sie RAD Studio neu. 30 | SetupMainInstallingPackages=Package werden installiert... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Paketinstallation nach Fehler wird rückgängig gemacht... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=Deinstallation abgebrochen! Schließen Sie alle Instanzen von RAD Studio, bevor Sie die Deinstallation durchführen. 33 | SetupMainUninstallingDetectedVersion=Andere Versionen werden deinstalliert... 34 | SetupMainUninstallingFromGetIt=Deinstallation von GetIt... 35 | SetupMainUninstallingPackages=Package werden deinstalliert... 36 | SetupOpenSamplesFolder=Beispielordner öffnen 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=Sie haben keine RAD Studio-Version ausgewählt und wenn Sie fortfahren, werden nur die Dateien extrahiert. Möchten Sie fortfahren? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=Zuerst öffnen 39 | SetupPagesRADStudioVersionsChoiceMessage=Wählen Sie die RAD Studio-Versionen aus, für die Sie %1 installieren möchten 40 | SetupPagesRADStudioVersionsChoiceTitle=RAD Studio auswählen 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Inoffizieller Support 42 | SetupUtilsPleaseReportThiIssue=%n%nBitte melden Sie dieses Problem. 43 | SetupViewOnlineDocumentation=Online-Dokumentation anzeigen -------------------------------------------------------------------------------- /Languages/Italian.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Completando il Setup di [name] 3 | FinishedLabel=Il Setup ha finito di installare [name] sul tuo computer. 4 | SetupWindowTitle=%1 Setup 5 | WelcomeLabel1=[name] Setup 6 | WelcomeLabel2=Questo Setup installerà la libreria [name/ver] sul tuo computer. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=Microsoft .NET Framework 3.5 SP1 non è stato trovato. 10 | DotNet45NotFound=Microsoft .NET Framework 4.5 non è stato trovato. 11 | RADStudioBuildBuildingFor=Compilazione per %1 - %2... 12 | RADStudioBuildErrorBuilding=Errore durante la compilazione per %1 (codice %2). 13 | RADStudioBuildErrorCantFoundRSVars=Impossibile trovare il file rsvars "%1" di %2. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=%1 non supporta la compilazione da riga di comando. È necessario installare manualmente la libreria. 15 | RADStudioProjectErrorParsingGroupProject=Errore durante l'analisi del progetto di gruppo "%1" (codice %2, riga %3, posizione %4, messaggio "%5"). 16 | RADStudioProjectErrorParsingProject=Errore durante l'analisi del progetto "%1" (codice %2, riga %3, posizione %4, messaggio "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Errore durante l'analisi del progetto "%1" (testo %2, messaggio "Personalità sconosciuta"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Errore imprevisto durante l'analisi del progetto di gruppo "%1" (messaggio "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Errore imprevisto durante l'analisi del progetto "%1" (messaggio "%2"). 20 | RADStudioUnknownVersionName=Nome sconosciuto 21 | SetupMainCouldNotDetectProjectBplOutputFileName=Impossibile rilevare il nome del file Bpl generato dal progetto "%1" di %2. 22 | SetupMainCouldNotUninstallDetectedVersion=Impossibile disinstallare altre versioni di %1 rilevate nel sistema. 23 | SetupMainCouldNotUninstallPackages=Impossibile disinstallare i Packages. 24 | SetupMainErrorFailedToGetGroupProjects=Impossibile ottenere i file dei progetti di gruppo. 25 | SetupMainErrorNoRADStudioVersionAvailable=Nessuna versione di RAD Studio disponibile nel sistema per l'installazione. 26 | SetupMainFailedToInstallPackage=Impossibile installare il Package "%1" in %2 (codice %3) 27 | SetupMainFailedToUninstallPackage=Impossibile disinstallare il Package "%1" in %2 (codice %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Chiudere RAD Studio prima di tentare l'installazione. Se è già stato chiuso, attendere un attimo prima di riprovare. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Installazione completata. Riavviare RAD Studio. 30 | SetupMainInstallingPackages=Installazione dei Packages in corso... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Ripristino dell'installazione dei Packages dopo l'errore... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=Disinstallazione annullata! Chiudere tutte le istanze di RAD Studio prima di procedere. 33 | SetupMainUninstallingDetectedVersion=Disinstallazione di altre versioni in corso... 34 | SetupMainUninstallingFromGetIt=Disinstallazione da GetIt in corso... 35 | SetupMainUninstallingPackages=Disinstallazione dei Packages in corso... 36 | SetupOpenSamplesFolder=Apri cartella esempi 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=Non è stata scelta alcuna versione di RAD Studio e, procedendo, verranno estratti solo i file. Si desidera continuare? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=È necessario aprirlo prima 39 | SetupPagesRADStudioVersionsChoiceMessage=Selezionare le versioni di RAD Studio per cui si desidera installare %1 40 | SetupPagesRADStudioVersionsChoiceTitle=Scegliere RAD Studio 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Supporto non ufficiale 42 | SetupUtilsPleaseReportThiIssue=%n%nSi prega di segnalare questo problema. 43 | SetupViewOnlineDocumentation=Visualizza documentazione online -------------------------------------------------------------------------------- /Languages/Spanish.isl: -------------------------------------------------------------------------------- 1 | [Messages] 2 | FinishedHeadingLabel=Finalizando la instalación de [name] 3 | FinishedLabel=La instalación de [name] ha finalizado en su computadora. 4 | SetupWindowTitle=Instalación de %1 5 | WelcomeLabel1=Instalación de [name] 6 | WelcomeLabel2=Este programa instalará la biblioteca [name/ver] en su computadora. 7 | 8 | [CustomMessages] 9 | DotNet35NotFound=No se encontró Microsoft .NET Framework 3.5 SP1. 10 | DotNet45NotFound=No se encontró Microsoft .NET Framework 4.5. 11 | RADStudioBuildBuildingFor=Compilando para %1 - %2... 12 | RADStudioBuildErrorBuilding=Error al compilar para %1 (código %2). 13 | RADStudioBuildErrorCantFoundRSVars=No se pudo encontrar el archivo rsvars "%1" de %2. 14 | RADStudioBuildErrorNotSupportCommandLineBuild=%1 no admite compilación por línea de comandos. Debe instalar la biblioteca manualmente. 15 | RADStudioProjectErrorParsingGroupProject=Error al analizar el proyecto de grupo "%1" (código %2, línea %3, posición %4, mensaje "%5"). 16 | RADStudioProjectErrorParsingProject=Error al analizar el proyecto "%1" (código %2, línea %3, posición %4, mensaje "%5"). 17 | RADStudioProjectErrorParsingProjectUnknownPersonality=Error al analizar el proyecto "%1" (texto %2, mensaje "Personalidad desconocida"). 18 | RADStudioProjectErrorUnexpectedParsingGroupProject=Error inesperado al analizar el proyecto de grupo "%1" (mensaje "%2"). 19 | RADStudioProjectErrorUnexpectedParsingProject=Error inesperado al analizar el proyecto "%1" (mensaje "%2"). 20 | RADStudioUnknownVersionName=Nombre desconocido 21 | SetupMainCouldNotDetectProjectBplOutputFileName=No se pudo detectar el nombre del archivo Bpl generado por el proyecto "%1" de %2. 22 | SetupMainCouldNotUninstallDetectedVersion=No se pudieron desinstalar otras versiones de %1 detectadas en su sistema. 23 | SetupMainCouldNotUninstallPackages=No se pudieron desinstalar los Packages. 24 | SetupMainErrorFailedToGetGroupProjects=Error al obtener los archivos de proyectos de grupo. 25 | SetupMainErrorNoRADStudioVersionAvailable=No hay versiones de RAD Studio disponibles en su sistema para la instalación. 26 | SetupMainFailedToInstallPackage=Error al instalar el Package "%1" en %2 (código %3) 27 | SetupMainFailedToUninstallPackage=Error al desinstalar el Package "%1" en %2 (código %3) 28 | SetupMainInstallAbortedToCloseRADStudioInstance=Por favor, cierre RAD Studio antes de intentar la instalación. Si ya lo ha cerrado, espere un momento antes de intentarlo de nuevo. 29 | SetupMainInstallationSuccesfullyRestartRADStudio=Instalación completada. Por favor, reinicie RAD Studio. 30 | SetupMainInstallingPackages=Instalando Packages... 31 | SetupMainRevertingPackagesInstallationAfterFailure=Revirtiendo la instalación de Packages después de un error... 32 | SetupMainUninstallAbortedToCloseRADStudioInstance=¡Desinstalación cancelada! Cierre todas las instancias de RAD Studio antes de desinstalar. 33 | SetupMainUninstallingDetectedVersion=Desinstalando otras versiones... 34 | SetupMainUninstallingFromGetIt=Desinstalando desde GetIt... 35 | SetupMainUninstallingPackages=Desinstalando Packages... 36 | SetupOpenSamplesFolder=Abrir carpeta de ejemplos 37 | SetupPagesNoneRADStudioVersionsSelectedMessage=No ha seleccionado ninguna versión de RAD Studio y, si continúa, solo se extraerán los archivos. ¿Desea continuar? 38 | SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst=Necesita abrirlo primero 39 | SetupPagesRADStudioVersionsChoiceMessage=Seleccione las versiones de RAD Studio para las que desea instalar %1 40 | SetupPagesRADStudioVersionsChoiceTitle=Elegir RAD Studio 41 | SetupPagesRADStudioVersionsChoiceUnofficialSupport=Soporte no oficial 42 | SetupUtilsPleaseReportThiIssue=%n%nPor favor, informe de este problema. 43 | SetupViewOnlineDocumentation=Ver documentación en línea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InnoSetup Scripts for Embarcadero RAD Studio© Components Installer 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | ## A collection of InnoSetup Scripts to build a RAD Studio Setup for Delphi Packages of Components and Libraries of any types. 6 | 7 | ### Actual official version 1.1.0 8 | 9 | Copyright © 2024-2025 Ethea S.r.l. 10 | Original Code is Copyright © 2021-2025 Skia4Delphi Project. 11 | Use of this source code is governed by the MIT license. 12 | 13 | ## Scope of this Scripts collection 14 | 15 | Many developers of Delphi components/libraries release their sources on Git-Hub, providing instructions for manually installing the packages. 16 | 17 | Using these scripts for InnoSetup Compiler it is possible to create an "automatic" Setup capable of: 18 | 19 | - Install the project in the folder selected by the user. 20 | - Copy all the files of the project (Sources, resources, Packages, help...). 21 | - Determine the versions of Delphi present on the machine. 22 | - Compile the packages (dcp), creating the 32 and 64 Bit dcu. 23 | - Install the Packages (bpl) in the CommonBplFolder of Delphi 24 | - Create an environment variable 25 | - Add search paths using the environment variable 26 | 27 | During an update, Setup is also capable to: 28 | 29 | - Uninstall the previous version of the Packages (eventually from Get-It) 30 | - Remove old sources and files 31 | - Delete old .dcp and .bpl files from CommonBplFolder and CommonDcpFolder 32 | - Proceed with the new Installation 33 | 34 | After the installation, the components/libraries are available into the IDE of Delphi and ready to use! 35 | 36 | ## How to use 37 | 38 | Prerequisites: download and install latest [Inno Setup Compiler](https://jrsoftware.org/download.php/is.exe?site=1) 39 | 40 | ### Files preparation: 41 | 42 | 1. In your components/Library Project create a Setup Folder 43 | 2. Clone this Repo into Setup/InnoSetupScripts 44 | 3. Place the "\Template\Setup.iss" file into your Setup Folder 45 | 4. Copy \Template\*.bmp files into your Setup Folder (WizClassicImage.bmp and WizClassicSmallImage.bmp) 46 | 47 | Verify to have this structure: 48 | ```Shell 49 | Setup 50 | │ Setup.iss 51 | │ WizClassicImage.bmp 52 | │ WizClassicSmallImage.bmp 53 | └─\InnoSetupScripts 54 | │ └─\Languages 55 | │ Default.isl 56 | │ Italian.isl 57 | │ ... 58 | └───\Scripts 59 | │ Setup.Preprocessor.ClearFiles.bat 60 | └───\Source 61 | │ Setup.Main.inc 62 | │ RADStudio.inc 63 | │ ... 64 | └───\Style 65 | │ Amakrits.vsf 66 | │ ... 67 | │ YellowGraphite.vsf 68 | │ Setup.Styles.dll 69 | ``` 70 | 71 | ### Customize Setup: 72 | 73 | 1. Customize your graphics changing the content of the bitmaps WizClassicImage.bmp and WizClassicSmallImage.bmp 74 | 2. Open "Setup.iss" with Inno Setup Compiler IDE and change values after "TODO:" lables 75 | 76 | ## Prepare your Packages for Build 77 | 78 | The Setup scripts automatically search in your Package folder all the packages to install, inside a GroupProject file. 79 | 80 | ### Setup your Package Groups: 81 | 82 | You must collect your packages in PackageGroups. 83 | 84 | Into every Package Group you must create a "Build group" called "ALL" in this way: 85 | 86 | 1. Open the PackageGroup file (.groupproj) 87 | 88 | 1. Click tothe Icon "Show Build Groups Pane" in the toolbar 89 | 90 | 1. In the "Build Groups Panel", click to the icon "Create a new build group" 91 | 92 | 1. Input "ALL" as the name of the Build Group 93 | 94 | 1. All of your packages are created and selected by default 95 | 96 | 1. Change the column "Configurations" to include Release (and also Debug if you want to provide also .dcu in debug mode) 97 | 98 | 1. Change the column "Platforms" to include Win64 (only for run-time packages) 99 | 100 | This is an example of the "Build Groups Panel": 101 | 102 | ![Build_Groups_Panel_Example](./Build_Groups_Panel_Example.jpg) 103 | 104 | ### WARNING: 105 | 106 | Check in your .dproj xml file, if contains the correct "ProjectVersion" number, because the scripts use it to known the correct Delphi Version. 107 | 108 | for Example, for Delphi 12.3 ProjectVersion must be 20.3: 109 | 110 | ```xml 111 | 112 | 113 | {00000000-0000-0000-0000-000000000000} 114 | PackageName.dpk 115 | 20.2 116 | ``` 117 | 118 | Use this table for the correct "ProjectVersion" of every Delphi versions: 119 | 120 | | RAD Studio Version | Min ProjectVersion | Max ProjectVersion | LibSuffix** | 121 | | :----------------------- | :----------------- | :----------------- | :------------- | 122 | | RAD Studio XE3 | 14.0 | 14.4 | 170 | 123 | | RAD Studio XE6 | 15.1 | 15.4 | 200 | 124 | | RAD Studio XE7 | 16.0 | 16.1 | 210 | 125 | | RAD Studio XE8 | 17.1 | 17.2 | 220 | 126 | | RAD Studio 10.0 Seattle | 18.0 | 18.1\* | 230 | 127 | | RAD Studio 10.1 Berlin | 18.1\* | 18.2\* | 240 | 128 | | RAD Studio 10.2 Tokyo | 18.2\* | 18.4 | 250 | 129 | | RAD Studio 10.3 Rio | 18.5 | 18.8 | 260 | 130 | | RAD Studio 10.4 Sydney | 19.0 | 19.2 | 270 or $(Auto) | 131 | | RAD Studio 11 Alexandria | 19.3 | 19.5 | 280 or $(Auto) | 132 | | RAD Studio 12 Athens | 20.1 | 20.3 | 290 or $(Auto) | 133 | 134 | \*In case of conflict the script searches for Package Version\*\* (LibSuffix), so it is recommended to use "standard" Lib Suffix values. 135 | 136 | If you need other versions not included in this table you must edit RADStudio.inc file to include them in: 137 | 138 | ```Pascal 139 | procedure _InitializationUnitRADStudio 140 | ``` 141 | 142 | ## Compile and Run Installer 143 | 144 | Build and Run Setup.iss to check your installation and debug the Setup. 145 | 146 | Check your "graphics" in first page (WizClassicImage.bmp) and in another pages (WizClassicSmallImage.bmp) 147 | 148 | Check if the Setup acquire your Delphi versions available. 149 | 150 | ![Setup](./Setup.png) 151 | 152 | If you have some problems to Build and install packages read carefully the log provided by the installer. 153 | 154 | After the installation check your Evironment Variable in Delphi IDE and Search Paths added by the installer. 155 | 156 | # License 157 | 158 | ## Copyright © 2024-2025 Ethea S.r.l. 159 | 160 | License [MIT-License](https://github.com/skia4delphi/skia4delphi?tab=MIT-1-ov-file) 161 | 162 | ## The original author of the Scripts are: Skia4Delphi Library by [the authors](https://skia4delphi.org/) 163 | 164 | License [MIT-License](https://github.com/skia4delphi/skia4delphi?tab=MIT-1-ov-file) 165 | 166 | ### RELEASE NOTES 167 | 27 Feb 2025: version 1.1.0 168 | - Added support to build design-time 64bit Packages for Delphi 12.3 169 | - Added support for Delphi 12.3 170 | 171 | 2 Jan 2025: version 1.0.0 172 | - Added support for bpl packages built in RAD Studio Common Bpl Folders 173 | - Added various Styles form customization of Setup 174 | - Added Italian language translation 175 | 176 | -------------------------------------------------------------------------------- /Scripts/Setup.Preprocessor.ClearFiles.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem # 4 | rem # Copyright (c) 2024-2025 (Ethea S.r.l.) 5 | rem # 6 | rem # Original code is Copyright (c) 2021-2024 Skia4Delphi Project. 7 | rem # 8 | rem # Use of this source code is governed by the MIT license that can be 9 | rem # found in the LICENSE file. 10 | rem # 11 | 12 | echo Cleaning Library Path (Lib)... 13 | for /f "tokens=* delims=" %%i in ('dir "..\..\..\Lib\" /s /b /a:-d ^| find /v "\Win32\Release\" ^| find /v "\Win64\Release\"') do ( 14 | echo Deleting "%%i" 15 | del "%%i" 16 | ) 17 | -------------------------------------------------------------------------------- /Setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Setup.png -------------------------------------------------------------------------------- /Source/IO.Utils.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitIOUtils 2 | #define UnitIOUtils 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit IO.Utils; 18 | 19 | // interface 20 | 21 | type 22 | TSearchOption = (soTopDirectoryOnly, soAllDirectories); 23 | 24 | /// Combine two paths (including combination of directory and filename) 25 | function CombinePath(const APath, ASubPath: string): string; forward; 26 | /// Copy directory folder 27 | function CopyDirectory(const AOriginPath, ADestPath: string; const AOverwriteExisting: Boolean): Boolean; forward; 28 | /// Copy file to a directory in a "force" mode (creating the path if not exists and overwrite existing) 29 | function CopyFileToDir(const AFileName, ADestPath: string): Boolean; forward; 30 | /// Get files of a path with an optional filename. The filename accepts the wildcard *, like "*.json" 31 | function GetFiles(APath, AFileName: string; const ASearchOption: TSearchOption): TArrayOfString; forward; 32 | /// Replace all matches of a folder name in a path 33 | function ReplaceFolderNameInPath(const APath, AOldFolderName, ANewFolderName: string; const ACaseSensitive: Boolean): string; forward; 34 | /// Replace all matches of a string in a file and return the success in load and save the file (even without changes) 35 | function ReplaceStringInFile(const AFileName, AOldValue, ANewValue: string; const ACaseSensitive: Boolean): Boolean; forward; 36 | 37 | // implementation 38 | 39 | // uses 40 | #include ".\String.Utils.inc" 41 | 42 | function CombinePath(const APath, ASubPath: string): string; 43 | begin 44 | Result := ASubPath; 45 | if StartsWithText(Result, '\') then 46 | Result := Copy(Result, 2, Length(Result) - 1); 47 | Result := AddBackslash(APath) + Result; 48 | end; 49 | 50 | function CopyDirectory(const AOriginPath, ADestPath: string; const AOverwriteExisting: Boolean): Boolean; 51 | var 52 | LOriginFilePath: string; 53 | LDestFilePath: string; 54 | LDestFileName: string; 55 | LFiles: TArrayOfString; 56 | I: Integer; 57 | begin 58 | Result := DirExists(ADestPath) or ForceDirectories(ADestPath); 59 | if Result then 60 | begin 61 | LFiles := GetFiles(AOriginPath, '*', soAllDirectories); 62 | for I := 0 to GetArrayLength(LFiles) - 1 do 63 | begin 64 | LOriginFilePath := ExtractFilePath(LFiles[I]); 65 | LDestFilePath := CombinePath(ADestPath, Copy(LOriginFilePath, Length(AOriginPath) + 1, Length(LOriginFilePath) - (Length(AOriginPath) + 1))); 66 | if not DirExists(LDestFilePath) then 67 | begin 68 | Result := ForceDirectories(LDestFilePath); 69 | if not Result then 70 | begin 71 | Log(Format('IO.Utils.CopyDirectory: Failed to create the dir "%s"', [LDestFilePath])); 72 | Exit; 73 | end; 74 | end; 75 | LDestFileName := CombinePath(LDestFilePath, ExtractFileName(LFiles[I])); 76 | if (not AOverwriteExisting) and FileExists(LDestFileName) then 77 | Continue; 78 | Result := FileCopy(LFiles[I], LDestFileName, not AOverwriteExisting); 79 | if not Result then 80 | begin 81 | Log(Format('IO.Utils.CopyDirectory: Failed to copy the file "%s" to "%s".', [LFiles[I], LDestFileName])); 82 | Exit; 83 | end; 84 | end; 85 | end 86 | else 87 | Log(Format('IO.Utils.CopyDirectory: Failed to create the directory "%s".', [ADestPath])); 88 | end; 89 | 90 | function CopyFileToDir(const AFileName, ADestPath: string): Boolean; 91 | begin 92 | Result := FileExists(AFileName) and (DirExists(ADestPath) or ForceDirectories(ADestPath)) and 93 | FileCopy(AFileName, CombinePath(ADestPath, ExtractFileName(AFileName)), False); 94 | end; 95 | 96 | function GetFiles(APath, AFileName: string; const ASearchOption: TSearchOption): TArrayOfString; 97 | var 98 | LFindRec: TFindRec; 99 | LSubDirResult: TArrayOfString; 100 | I: Integer; 101 | begin 102 | Result := []; 103 | APath := AddBackslash(APath); 104 | 105 | if FindFirst(APath + AFileName, LFindRec) then 106 | begin 107 | try 108 | repeat 109 | if (LFindRec.Name <> '.') and (LFindRec.Name <> '..') and 110 | ((LFindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY) = 0) and FileExists(APath + LFindRec.Name) then 111 | begin 112 | SetArrayLength(Result, GetArrayLength(Result) + 1); 113 | Result[GetArrayLength(Result) - 1] := APath + LFindRec.Name; 114 | end; 115 | until not FindNext(LFindRec); 116 | finally 117 | FindClose(LFindRec); 118 | end; 119 | end; 120 | 121 | if (ASearchOption = soAllDirectories) and FindFirst(APath + '*', LFindRec) then 122 | begin 123 | try 124 | repeat 125 | if (LFindRec.Name <> '.') and (LFindRec.Name <> '..') and 126 | DirExists(AddBackslash(APath + LFindRec.Name)) then 127 | begin 128 | LSubDirResult := GetFiles(AddBackslash(APath + LFindRec.Name), AFileName, ASearchOption); 129 | for I := 0 to GetArrayLength(LSubDirResult) -1 do 130 | begin 131 | SetArrayLength(Result, GetArrayLength(Result) + 1); 132 | Result[GetArrayLength(Result) - 1] := LSubDirResult[I]; 133 | end; 134 | end; 135 | until not FindNext(LFindRec); 136 | finally 137 | FindClose(LFindRec); 138 | end; 139 | end; 140 | end; 141 | 142 | function ReplaceFolderNameInPath(const APath, AOldFolderName, ANewFolderName: string; const ACaseSensitive: Boolean): string; 143 | begin 144 | Result := JoinStrings(ReplaceString(SplitString(APath, '\'), AOldFolderName, ANewFolderName, ACaseSensitive, True), '\', False); 145 | end; 146 | 147 | function ReplaceStringInFile(const AFileName, AOldValue, ANewValue: string; const ACaseSensitive: Boolean): Boolean; 148 | var 149 | LLines: TArrayOfString; 150 | begin 151 | Result := LoadStringsFromFile(AFileName, LLines) and SaveStringsToUTF8File(AFileName, ReplaceString(LLines, AOldValue, ANewValue, ACaseSensitive, False), False); 152 | if not Result then 153 | Log(Format('IO.Utils.ReplaceStringInFile: Failed to load or save strings in file "%s".', [AFileName])); 154 | end; 155 | 156 | // end. 157 | #endif 158 | -------------------------------------------------------------------------------- /Source/RADStudio.Build.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitRADStudioBuild 2 | #define UnitRADStudioBuild 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit RADStudio.Build; 18 | 19 | // interface 20 | 21 | // uses 22 | #include ".\RADStudio.inc" 23 | #include ".\RADStudio.Project.inc" 24 | 25 | type 26 | TBeforeProjectBuildFunc = function(const AProject: TRADStudioProject; const APlatform: TProjectPlatform; const AInfo: TRADStudioInfo): Boolean; 27 | TTryExtractPreBuildObjectsProc = function(const AInfo: TRADStudioInfo): Boolean; 28 | 29 | /// Get platforms that are allowed to build in specific platform. Current, allowed only windows platforms to avoid problems with sdk. 30 | function GetPlatformsAllowedToBuild(const ARADStudioInfo: TRADStudioInfo): TProjectPlatforms; forward; 31 | /// Get steps of TryBuildRADStudioPackages used in WizardForm.ProgressGauge.Position. Use this to set WizardForm.ProgressGauge.Max before call the TryBuildRADStudioPackages. 32 | function GetTryBuildRADStudioPackagesSteps(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects): Integer; forward; 33 | /// Try to build RAD Studio packages, but only in allowed platforms. 34 | function TryBuildRADStudioPackages(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects; const ACustomParameter: string; const ABeforeProjectBuild: TBeforeProjectBuildFunc; const ATryExtractPreBuildObjects: TTryExtractPreBuildObjectsProc): Boolean; forward; 35 | 36 | // implementation 37 | 38 | // uses 39 | #include ".\IO.Utils.inc" 40 | #include ".\Setup.Utils.inc" 41 | 42 | const 43 | _BuilLogsFileName = '{app}\Build.Logs.txt'; 44 | 45 | /// Get the MSBuild parameters. The custom parameter is optionally. 46 | function _GetMSBuildParams(const AConfig: TProjectConfig; const APlatform: TProjectPlatform; const ACustomParameter: string): string; forward; 47 | /// Try to get the comand to build a project. The custom parameter is optionally. 48 | function _TryBuildRADStudioProject(const ARADStudioInfo: TRADStudioInfo; const AConfig: TProjectConfig; const APlatform: TProjectPlatform; const AProject: TRADStudioProject; const ACustomParameter, ALogFileName: string; const ABeforeProjectBuild: TBeforeProjectBuildFunc; out AResultCode: Integer): Boolean; forward; 49 | /// Try to get the comand to build a project. The custom parameter is optionally. 50 | function _TryGetBuildCommand(const ARADStudioInfo: TRADStudioInfo; const AConfig: TProjectConfig; const APlatform: TProjectPlatform; const AProjectFileName, ACustomParameter, ALogFileName: string; out ACommand: string): Boolean; forward; 51 | 52 | function _GetMSBuildParams(const AConfig: TProjectConfig; const APlatform: TProjectPlatform; const ACustomParameter: string): string; 53 | begin 54 | Result := Format('/p:Config=%s /p:Platform=%s /p:DCC_BuildAllUnits=true', [GetProjectConfigName(AConfig), GetProjectPlatformName(APlatform)]); 55 | if ACustomParameter <> '' then 56 | Result := Result + Format(' /p:%s', [ACustomParameter]); 57 | end; 58 | 59 | function GetPlatformsAllowedToBuild(const ARADStudioInfo: TRADStudioInfo): TProjectPlatforms; 60 | begin 61 | Result := [pfWin32, pfWin64]; 62 | end; 63 | 64 | function GetTryBuildRADStudioPackagesSteps(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects): Integer; 65 | var 66 | I, J, K: Integer; 67 | LInfo: TRADStudioInfo; 68 | LProject: TRADStudioProject; 69 | LVersion: TRADStudioVersion; 70 | LPlatform: TProjectPlatform; 71 | begin 72 | Result := 0; 73 | for I := 0 to GetArrayLength(ARADStudioInfos) - 1 do 74 | begin 75 | LInfo := ARADStudioInfos[I]; 76 | if LInfo.Status <> riNormal then 77 | Continue; 78 | for LPlatform := LowProjectPlatform to HighProjectPlatform do 79 | begin 80 | if not (LPlatform in GetPlatformsAllowedToBuild(LInfo)) then 81 | Continue; 82 | for J := 0 to GetArrayLength(AGroupProjects) - 1 do 83 | begin 84 | for K := 0 to GetArrayLength(AGroupProjects[J].Items) - 1 do 85 | begin 86 | LProject := AGroupProjects[J].Items[K].Project; 87 | if TryGetRADStudioVersionOfProject(LProject, LVersion) and (CompareRADStudioVersions(LVersion, LInfo.Version) = 0) and (LPlatform in LProject.Platforms) then 88 | Result := Result + 1; 89 | end; 90 | end; 91 | end; 92 | end; 93 | end; 94 | 95 | function TryBuildRADStudioPackages(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects; const ACustomParameter: string; 96 | const ABeforeProjectBuild: TBeforeProjectBuildFunc; const ATryExtractPreBuildObjects: TTryExtractPreBuildObjectsProc): Boolean; 97 | var 98 | I, J, K: Integer; 99 | LInfo: TRADStudioInfo; 100 | LProject: TRADStudioProject; 101 | LVersion: TRADStudioVersion; 102 | LPlatform: TProjectPlatform; 103 | LResultCode: Integer; 104 | begin 105 | Log('RADStudio.Build.TryBuildRADStudioPackages: Starting...'); 106 | for I := 0 to GetArrayLength(ARADStudioInfos) - 1 do 107 | begin 108 | LInfo := ARADStudioInfos[I]; 109 | if not (LInfo.Status in [riNormal, riToolchainNotSupported]) then 110 | Continue; 111 | for LPlatform := LowProjectPlatform to HighProjectPlatform do 112 | begin 113 | if not (LPlatform in GetPlatformsAllowedToBuild(LInfo)) then 114 | Continue; 115 | for J := 0 to GetArrayLength(AGroupProjects) - 1 do 116 | begin 117 | for K := 0 to GetArrayLength(AGroupProjects[J].Items) - 1 do 118 | begin 119 | LProject := AGroupProjects[J].Items[K].Project; 120 | if TryGetRADStudioVersionOfProject(LProject, LVersion) and (CompareRADStudioVersions(LVersion, LInfo.Version) = 0) and (LPlatform in LProject.Platforms) then 121 | begin 122 | Log(Format('RADStudio.Build.TryBuildRADStudioPackages: Trying to build the package "%s" to %s platform for %s', [LProject.FileName, GetProjectPlatformName(LPlatform), LInfo.Version.Name])); 123 | WizardForm.StatusLabel.Caption := FmtMessage(CustomMessage('RADStudioBuildBuildingFor'), [LInfo.Version.Name, GetProjectPlatformName(LPlatform)]); 124 | WizardForm.FilenameLabel.Caption := ExtractFileName(LProject.FileName); 125 | if (LInfo.Status = riToolchainNotSupported) or (not _TryBuildRADStudioProject(LInfo, LInfo.BuildConfig, LPlatform, LProject, ACustomParameter, ExpandConstant(_BuilLogsFileName), ABeforeProjectBuild, LResultCode)) then 126 | begin 127 | Log(Format('RADStudio.Build.TryBuildRADStudioPackages: Failed to build the package "%s" to %s platform for %s', [LProject.FileName, GetProjectPlatformName(LPlatform), LInfo.Version.Name])); 128 | if (ATryExtractPreBuildObjects <> nil) and ATryExtractPreBuildObjects(LInfo) then 129 | begin 130 | Log(Format('RADStudio.Build.TryBuildRADStudioPackages: Extracted pre-build objects for %s', [LInfo.Version.Name])); 131 | Break; 132 | end 133 | else 134 | begin 135 | if LInfo.Status = riToolchainNotSupported then 136 | TryShowErrorFmt(CustomMessage('RADStudioBuildErrorNotSupportCommandLineBuild'), [LInfo.Version.Name]) 137 | else 138 | begin 139 | TryShowErrorFmt(CustomMessage('RADStudioBuildErrorBuilding'), [LInfo.Version.Name + ' - ' + ExtractFileName(LProject.FileName) + ' - ' + GetProjectPlatformName(LPlatform), InttoStr(LResultCode)]); 140 | TryOpenInNotepad(ExpandConstant(_BuilLogsFileName)); 141 | end; 142 | end; 143 | Result := False; 144 | Exit; 145 | end; 146 | WizardForm.ProgressGauge.Position := WizardForm.ProgressGauge.Position + 1; 147 | end; 148 | end; 149 | end; 150 | end; 151 | end; 152 | Result := True; 153 | end; 154 | 155 | function _TryBuildRADStudioProject(const ARADStudioInfo: TRADStudioInfo; const AConfig: TProjectConfig; const APlatform: TProjectPlatform; 156 | const AProject: TRADStudioProject; const ACustomParameter, ALogFileName: string; const ABeforeProjectBuild: TBeforeProjectBuildFunc; out AResultCode: Integer): Boolean; 157 | var 158 | LProjectDir, LVersion: string; 159 | LCommand: string; 160 | LBuild: Boolean; 161 | begin 162 | DeleteFile(ALogFileName); 163 | Result := _TryGetBuildCommand(ARADStudioInfo, AConfig, APlatform, AProject.FileName, ACustomParameter, ALogFileName, LCommand); 164 | if Result then 165 | begin 166 | AResultCode := 0; 167 | LProjectDir := ExtractFilePath(AProject.FileName); 168 | LBuild := True; 169 | if ABeforeProjectBuild <> nil then 170 | LBuild := ABeforeProjectBuild(AProject, APlatform, ARADStudioInfo); 171 | if LBuild then 172 | begin 173 | Result := Exec(ExpandConstant('{cmd}'), '/C ' + LCommand, LProjectDir, SW_HIDE, ewWaitUntilTerminated, AResultCode) and (AResultCode = 0) 174 | if Result then 175 | DeleteFile(ALogFileName) 176 | else 177 | begin 178 | LVersion := ARADStudioInfo.Version.RegVersion; 179 | //Check if we are building a 64Bit Design-Time Package: do not stop process, for backward compatibility with Delphi 12.2 180 | if (APlatform = pfWin64) and AProject.IsDesignOnly and (LVersion = '23.0') then 181 | Result := True 182 | else 183 | Log(Format('RADStudio.Build._TryBuildRADStudioProject: Failed executing command "%s"', [LCommand])); 184 | end; 185 | end 186 | else 187 | Log(Format('RADStudio.Build._TryBuildRADStudioProject: Skipped Build of Package "%s"', [AProject.FileName])); 188 | end; 189 | end; 190 | 191 | function _TryGetBuildCommand(const ARADStudioInfo: TRADStudioInfo; const AConfig: TProjectConfig; const APlatform: TProjectPlatform; const AProjectFileName, ACustomParameter, ALogFileName: string; out ACommand: string): Boolean; 192 | var 193 | LFrameworkDir: string; 194 | LResultCode: Integer; 195 | LRSVarsBatchFileName: string; 196 | begin 197 | Result := TryGetRADStudioRSVarsBatchFileName(ARADStudioInfo, LRSVarsBatchFileName); 198 | if not Result then 199 | TryShowErrorFmt(CustomMessage('RADStudioBuildErrorCantFoundRSVars'), [LRsVarsBatchFileName, ARADStudioInfo.Version.Name]) 200 | else 201 | begin 202 | if Exec(ExpandConstant('{cmd}'), Format('/C ""%s" && MSBuild /version>nul 2>&1"', [LRSVarsBatchFileName]), '', SW_HIDE, ewWaitUntilTerminated, LResultCode) and (LResultCode = 0) then 203 | ACommand := Format('""%s" && MSBuild "%s" %s>"%s" 2>&1"', [LRSVarsBatchFileName, AProjectFileName, _GetMSBuildParams(AConfig, APlatform, ACustomParameter), ALogFileName]) 204 | else 205 | begin 206 | Result := IsDotNetInstalled(ARADStudioInfo.Version.DotNetVersion, ARADStudioInfo.Version.DotNetServicePack); 207 | if not Result then 208 | begin 209 | case ARADStudioInfo.Version.DotNetVersion of 210 | net35: TryShowError(CustomMessage('DotNet35NotFound')); 211 | net45: TryShowError(CustomMessage('DotNet45NotFound')); 212 | end; 213 | end 214 | else 215 | begin 216 | case ARADStudioInfo.Version.DotNetVersion of 217 | net35: LFrameworkDir := ExpandConstant('{dotnet20}'); 218 | net45: LFrameworkDir := ExpandConstant('{dotnet40}'); 219 | end; 220 | ACommand := Format('""%s" && @set "FrameworkDir=%s" && @set "PATH=%s;%%PATH%%" && MSBuild "%s" %s>"%s" 2>&1"', [LRSVarsBatchFileName, LFrameworkDir, LFrameworkDir, AProjectFileName, _GetMSBuildParams(AConfig, APlatform, ACustomParameter), ALogFileName]); 221 | end; 222 | end; 223 | end; 224 | end; 225 | 226 | // end. 227 | #endif 228 | -------------------------------------------------------------------------------- /Source/RADStudio.Project.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitRADStudioProject 2 | #define UnitRADStudioProject 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit RADStudio.Project; 18 | 19 | // interface 20 | 21 | type 22 | TProjectPlatform = (pfWin32, pfWin64, pfAndroid, pfAndroid64, pfiOSDevice32, pfiOSDevice64, pfiOSSimARM64, pfiOSSimulator, pfOSX32, pfOSX64, pfOSXARM64, pfLinux64); 23 | TProjectPlatforms = set of TProjectPlatform; 24 | TProjectConfig = (pcDebug, pcRelease); 25 | TProjectConfigs = set of TProjectConfig; 26 | TProjectPersonality = (ppCBuilder, ppDelphi); 27 | 28 | TRADStudioProject = record 29 | FileName: string; 30 | Description: string; 31 | SourceFiles: TArrayOfString; 32 | SourcePaths: TArrayOfString; 33 | BplOutputPath: string; 34 | DcpOutputPath: string; 35 | DCUOutputPath: string; 36 | DllSuffix: string; 37 | Platforms: TProjectPlatforms; 38 | ProjectVersion: string; 39 | Personality: TProjectPersonality; 40 | IsDesignOnly: Boolean; 41 | IsPackage: Boolean; 42 | IsInstallable: Boolean; 43 | RequiresDCPCount: Integer; 44 | end; 45 | 46 | TRADStudioGroupProjectItem = record 47 | Project: TRADStudioProject; 48 | Configs: TProjectConfigs; 49 | Platforms: TProjectPlatforms; 50 | end; 51 | 52 | TRADStudioGroupProjectItems = array of TRADStudioGroupProjectItem; 53 | 54 | TRADStudioGroupProject = record 55 | FileName: string; 56 | Items: TRADStudioGroupProjectItems; 57 | end; 58 | 59 | TRADStudioGroupProjects = array of TRADStudioGroupProject; 60 | 61 | /// Copy group project record 62 | function CopyRADStudioGroupProject(const AGroupProject: TRADStudioGroupProject): TRADStudioGroupProject; forward; 63 | /// Expand project path (directory or filename), expanding relative path, config and platform names 64 | function ExpandProjectPath(const APath: string; const AConfig: TProjectConfig; const APlatform: TProjectPlatform): string; forward; 65 | /// Get config name 66 | function GetProjectConfigName(const AConfig: TProjectConfig): string; forward; 67 | /// Get platform friendly name 68 | function GetProjectPlatformFriendlyName(const APlatform: TProjectPlatform): string; forward; 69 | /// Name of the platform used in library registry 70 | function GetProjectPlatformLibraryName(const APlatform: TProjectPlatform): string; forward; 71 | /// Get platform name 72 | function GetProjectPlatformName(const APlatform: TProjectPlatform): string; forward; 73 | /// Get the default DCP output Path + dcp filename of a RAD Studio project 74 | function GetRADStudioProjectDcpFileName(const AProject: TRADStudioProject): string; forward; 75 | /// Get the default DCP output Path + dcp filename of a RAD Studio project 76 | function GetRADStudioProjectDcpOutputFileName(const AProject: TRADStudioProject): string; forward; 77 | /// Replace the root path in all path/filename fields of RAD Studio group projects 78 | procedure ReplaceRootPathOfRADStudioGroupProjects(const AOldRootPath, ANewRootPath: string; var AGroupProjects: TRADStudioGroupProjects); forward; 79 | /// Change all paths/filename to absolute (removing relative paths) 80 | procedure SetAbsolutePathsInRADStudioGroupProjects(const ADefaultRootPath: string; var AGroupProjects: TRADStudioGroupProjects); forward; 81 | /// Try list and load all group projects from a path 82 | function TryGetRADStudioGroupProjectsFromPath(const APath: string; out AGroupProjects: TRADStudioGroupProjects): Boolean; forward; 83 | /// Try to load a RAD Studio group project 84 | function TryLoadRADStudioGroupProject(const AFileName: string; out AGroupProject: TRADStudioGroupProject): Boolean; forward; 85 | /// Try to load a RAD Studio project 86 | function TryLoadRADStudioProject(const AFileName: string; out AProject: TRADStudioProject): Boolean; forward; 87 | /// Try convert text to config 88 | function TryStrToProjectConfig(const AConfigName: string; out AConfig: TProjectConfig): Boolean; forward; 89 | /// Try convert text (with configs names separeted by ;) to configs 90 | function TryStrToProjectConfigs(const AText: string; out AConfigs: TProjectConfigs): Boolean; forward; 91 | /// Try convert text to platform 92 | function TryStrToProjectPlatform(const APlatformName: string; out APlatform: TProjectPlatform): Boolean; forward; 93 | /// Try convert text (with platforms names separeted by ;) to platforms 94 | function TryStrToProjectPlatforms(const AText: string; out APlatforms: TProjectPlatforms): Boolean; forward; 95 | 96 | const 97 | LowProjectPlatform = pfWin32; 98 | HighProjectPlatform = pfLinux64; 99 | LowProjectConfig = pcDebug; 100 | HighProjectConfig = pcRelease; 101 | 102 | // implementation 103 | 104 | // uses 105 | #include ".\IO.Utils.inc" 106 | #include ".\String.Utils.inc" 107 | #include ".\Setup.Utils.inc" 108 | 109 | /// Expand just the project root, adding a ADefaultRootPath if it doesn't have and expanding the filename to remove relative paths 110 | procedure _ExpandProjectRootPath(var APath: string; const ADefaultRootPath: string); forward; 111 | /// Ascendent sort of items of group project by RequiresDCPCount 112 | function _SortGroupProjectItems(AItems: TRADStudioGroupProjectItems): TRADStudioGroupProjectItems; forward; 113 | 114 | function CopyRADStudioGroupProject(const AGroupProject: TRADStudioGroupProject): TRADStudioGroupProject; 115 | var 116 | I, J: Integer; 117 | begin 118 | Result.FileName := AGroupProject.FileName; 119 | SetArrayLength(Result.Items, GetArrayLength(AGroupProject.Items)); 120 | for I := 0 to GetArrayLength(Result.Items) - 1 do 121 | begin 122 | Result.Items[I].Project.FileName := AGroupProject.Items[I].Project.FileName; 123 | Result.Items[I].Project.Description := AGroupProject.Items[I].Project.Description; 124 | Result.Items[I].Project.BplOutputPath := AGroupProject.Items[I].Project.BplOutputPath; 125 | Result.Items[I].Project.DcpOutputPath := AGroupProject.Items[I].Project.DcpOutputPath; 126 | Result.Items[I].Project.DCUOutputPath := AGroupProject.Items[I].Project.DCUOutputPath; 127 | Result.Items[I].Project.DllSuffix := AGroupProject.Items[I].Project.DllSuffix; 128 | Result.Items[I].Project.Platforms := AGroupProject.Items[I].Project.Platforms; 129 | Result.Items[I].Project.ProjectVersion := AGroupProject.Items[I].Project.ProjectVersion; 130 | Result.Items[I].Project.Personality := AGroupProject.Items[I].Project.Personality; 131 | Result.Items[I].Project.IsDesignOnly := AGroupProject.Items[I].Project.IsDesignOnly; 132 | Result.Items[I].Project.IsPackage := AGroupProject.Items[I].Project.IsPackage; 133 | Result.Items[I].Project.IsInstallable := AGroupProject.Items[I].Project.IsInstallable; 134 | Result.Items[I].Project.RequiresDCPCount := AGroupProject.Items[I].Project.RequiresDCPCount; 135 | SetArrayLength(Result.Items[I].Project.SourceFiles, GetArrayLength(AGroupProject.Items[I].Project.SourceFiles)); 136 | for J := 0 to GetArrayLength(AGroupProject.Items[I].Project.SourceFiles) - 1 do 137 | Result.Items[I].Project.SourceFiles[J] := AGroupProject.Items[I].Project.SourceFiles[J]; 138 | SetArrayLength(Result.Items[I].Project.SourcePaths, GetArrayLength(AGroupProject.Items[I].Project.SourcePaths)); 139 | for J := 0 to GetArrayLength(AGroupProject.Items[I].Project.SourcePaths) - 1 do 140 | Result.Items[I].Project.SourcePaths[J] := AGroupProject.Items[I].Project.SourcePaths[J]; 141 | Result.Items[I].Configs := AGroupProject.Items[I].Configs; 142 | Result.Items[I].Platforms := AGroupProject.Items[I].Platforms; 143 | end; 144 | end; 145 | 146 | function ExpandProjectPath(const APath: string; const AConfig: TProjectConfig; const APlatform: TProjectPlatform): string; 147 | begin 148 | Result := APath; 149 | StringChangeEx(Result, '$(Platform)', GetProjectPlatformName(APlatform), True); 150 | StringChangeEx(Result, '$(Config)', GetProjectConfigName(AConfig), True); 151 | Result := ExpandConstant(Result); 152 | if Pos('$(', Result) = 0 then 153 | Result := ExpandFileName(Result); 154 | end; 155 | 156 | procedure _ExpandProjectRootPath(var APath: string; const ADefaultRootPath: string); 157 | begin 158 | if ExtractFileDrive(APath) = '' then 159 | APath := CombinePath(ADefaultRootPath, APath); 160 | APath := ExpandFileName(APath); 161 | end; 162 | 163 | function GetProjectConfigName(const AConfig: TProjectConfig): string; 164 | begin 165 | case AConfig of 166 | pcDebug : Result := 'Debug'; 167 | pcRelease: Result := 'Release'; 168 | else 169 | Result := ''; 170 | end; 171 | end; 172 | 173 | function GetProjectPlatformFriendlyName(const APlatform: TProjectPlatform): string; 174 | begin 175 | case APlatform of 176 | pfWin32 : Result := 'Windows 32-bit'; 177 | pfWin64 : Result := 'Windows 64-bit'; 178 | pfAndroid : Result := 'Android 32-bit'; 179 | pfAndroid64 : Result := 'Android 64-bit'; 180 | pfiOSDevice32 : Result := 'iOS Device 32-bit'; 181 | pfiOSDevice64 : Result := 'iOS Device 64-bit'; 182 | pfiOSSimARM64 : Result := 'iOS Simulator ARM 64-bit'; 183 | pfiOSSimulator: Result := 'iOS Simulator'; 184 | pfOSX32 : Result := 'OSX 32-bit'; 185 | pfOSX64 : Result := 'OSX 64-bit'; 186 | pfOSXARM64 : Result := 'OSX ARM 64-bit'; 187 | pfLinux64 : Result := 'Linux 64-bit'; 188 | else 189 | Result := ''; 190 | end; 191 | end; 192 | 193 | function GetProjectPlatformLibraryName(const APlatform: TProjectPlatform): string; 194 | begin 195 | if APlatform = pfAndroid then 196 | Result := 'Android32' 197 | else if APlatform = pfiOSDevice32 then 198 | Result := 'iOSDevice' 199 | else 200 | Result := GetProjectPlatformName(APlatform); 201 | end; 202 | 203 | function GetProjectPlatformName(const APlatform: TProjectPlatform): string; 204 | begin 205 | case APlatform of 206 | pfWin32 : Result := 'Win32'; 207 | pfWin64 : Result := 'Win64'; 208 | pfAndroid : Result := 'Android'; 209 | pfAndroid64 : Result := 'Android64'; 210 | pfiOSDevice32 : Result := 'iOSDevice32'; 211 | pfiOSDevice64 : Result := 'iOSDevice64'; 212 | pfiOSSimARM64 : Result := 'iOSSimARM64'; 213 | pfiOSSimulator: Result := 'iOSSimulator'; 214 | pfOSX32 : Result := 'OSX32'; 215 | pfOSX64 : Result := 'OSX64'; 216 | pfOSXARM64 : Result := 'OSXARM64'; 217 | pfLinux64 : Result := 'Linux64'; 218 | else 219 | Result := ''; 220 | end; 221 | end; 222 | 223 | function GetRADStudioProjectDcpFileName(const AProject: TRADStudioProject): string; 224 | begin 225 | Result := ExtractFileName(ChangeFileExt(AProject.FileName, '.dcp')); 226 | end; 227 | 228 | function GetRADStudioProjectDcpOutputFileName(const AProject: TRADStudioProject): string; 229 | begin 230 | Result := AddBackslash(AProject.DcpOutputPath) + GetRADStudioProjectDcpFileName(AProject); 231 | end; 232 | 233 | procedure ReplaceRootPathOfRADStudioGroupProjects(const AOldRootPath, ANewRootPath: string; var AGroupProjects: TRADStudioGroupProjects); 234 | var 235 | I, J, K: Integer; 236 | LGroupProject: TRADStudioGroupProject; 237 | LGroupProjectItem: TRADStudioGroupProjectItem; 238 | LProject: TRADStudioProject; 239 | begin 240 | for I := 0 to GetArrayLength(AGroupProjects) - 1 do 241 | begin 242 | LGroupProject := AGroupProjects[I]; 243 | StringChangeEx(LGroupProject.FileName, AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 244 | for J := 0 to GetArrayLength(LGroupProject.Items) - 1 do 245 | begin 246 | LGroupProjectItem := LGroupProject.Items[J]; 247 | LProject := LGroupProjectItem.Project; 248 | StringChangeEx(LProject.FileName, AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 249 | for K := 0 to GetArrayLength(LProject.SourceFiles) - 1 do 250 | StringChangeEx(LProject.SourceFiles[K], AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 251 | for K := 0 to GetArrayLength(LProject.SourcePaths) - 1 do 252 | StringChangeEx(LProject.SourcePaths[K], AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 253 | StringChangeEx(LProject.BplOutputPath, AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 254 | StringChangeEx(LProject.DcpOutputPath, AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 255 | StringChangeEx(LProject.DCUOutputPath, AddBackslash(AOldRootPath), AddBackslash(ANewRootPath), True); 256 | LGroupProjectItem.Project := LProject; 257 | LGroupProject.Items[J] := LGroupProjectItem; 258 | end; 259 | AGroupProjects[I] := LGroupProject; 260 | end; 261 | end; 262 | 263 | procedure SetAbsolutePathsInRADStudioGroupProjects(const ADefaultRootPath: string; var AGroupProjects: TRADStudioGroupProjects); 264 | var 265 | I, J, K: Integer; 266 | LGroupProject: TRADStudioGroupProject; 267 | LGroupProjectItem: TRADStudioGroupProjectItem; 268 | LGroupProjectPath: string; 269 | LProject: TRADStudioProject; 270 | LProjectPath: string; 271 | begin 272 | for I := 0 to GetArrayLength(AGroupProjects) - 1 do 273 | begin 274 | LGroupProject := AGroupProjects[I]; 275 | _ExpandProjectRootPath(LGroupProject.FileName, ADefaultRootPath); 276 | LGroupProjectPath := ExtractFilePath(LGroupProject.FileName); 277 | for J := 0 to GetArrayLength(LGroupProject.Items) - 1 do 278 | begin 279 | LGroupProjectItem := LGroupProject.Items[J]; 280 | LProject := LGroupProjectItem.Project; 281 | _ExpandProjectRootPath(LProject.FileName, LGroupProjectPath); 282 | LProjectPath := ExtractFilePath(LProject.FileName); 283 | for K := 0 to GetArrayLength(LProject.SourceFiles) - 1 do 284 | _ExpandProjectRootPath(LProject.SourceFiles[K], LProjectPath); 285 | for K := 0 to GetArrayLength(LProject.SourcePaths) - 1 do 286 | _ExpandProjectRootPath(LProject.SourcePaths[K], LProjectPath); 287 | _ExpandProjectRootPath(LProject.BplOutputPath, LProjectPath); 288 | _ExpandProjectRootPath(LProject.DcpOutputPath, LProjectPath); 289 | _ExpandProjectRootPath(LProject.DCUOutputPath, LProjectPath); 290 | LGroupProjectItem.Project := LProject; 291 | LGroupProject.Items[J] := LGroupProjectItem; 292 | end; 293 | AGroupProjects[I] := LGroupProject; 294 | end; 295 | end; 296 | 297 | function _SortGroupProjectItems(AItems: TRADStudioGroupProjectItems): TRADStudioGroupProjectItems; 298 | var 299 | I: Integer; 300 | J: Integer; 301 | LMinIndex: Integer; 302 | LJProject, LMinProject: TRADStudioProject; 303 | LProject: TRADStudioProject; 304 | LResult: TRADStudioGroupProjectItems; 305 | begin 306 | SetArrayLength(LResult, GetArrayLength(AItems)); 307 | for I := 0 to GetArrayLength(AItems) - 1 do 308 | begin 309 | LMinIndex := I; 310 | for J := 0 to GetArrayLength(AItems) - 1 do 311 | begin 312 | LJProject := AItems[J].Project; 313 | LMinProject := AItems[LMinIndex].Project; 314 | if (LJProject.RequiresDCPCount <> -1) and ((LJProject.RequiresDCPCount < LMinProject.RequiresDCPCount) or 315 | ((LJProject.RequiresDCPCount = LMinProject.RequiresDCPCount) and (CompareText(LJProject.FileName, LMinProject.FileName) < 0)) or 316 | (LMinProject.RequiresDCPCount = -1)) then 317 | begin 318 | LMinIndex := J; 319 | end; 320 | end; 321 | LResult[I] := AItems[LMinIndex]; 322 | LProject := AItems[LMinIndex].Project; 323 | LProject.RequiresDCPCount := -1; 324 | AItems[LMinIndex].Project := LProject; 325 | end; 326 | Result := LResult; 327 | end; 328 | 329 | function TryGetRADStudioGroupProjectsFromPath(const APath: string; out AGroupProjects: TRADStudioGroupProjects): Boolean; 330 | var 331 | LGroupProjectFiles: TArrayOfString; 332 | LGroupProject: TRADStudioGroupProject; 333 | I: Integer; 334 | begin 335 | Result := True; 336 | AGroupProjects := []; 337 | LGroupProjectFiles := GetFiles(APath, '*.groupproj', soAllDirectories); 338 | for I := 0 to GetArrayLength(LGroupProjectFiles) - 1 do 339 | begin 340 | if not TryLoadRADStudioGroupProject(LGroupProjectFiles[I], LGroupProject) then 341 | begin 342 | Result := False; 343 | Exit; 344 | end; 345 | SetArrayLength(AGroupProjects, GetArrayLength(AGroupProjects) + 1); 346 | AGroupProjects[GetArrayLength(AGroupProjects) - 1] := LGroupProject; 347 | end; 348 | end; 349 | 350 | function TryLoadRADStudioGroupProject(const AFileName: string; out AGroupProject: TRADStudioGroupProject): Boolean; 351 | var 352 | LItem: TRADStudioGroupProjectItem; 353 | LXMLNodeList: Variant; 354 | LXMLDocument: Variant; 355 | LAttributeValue: string; 356 | I: Integer; 357 | begin 358 | Result := FileExists(AFileName); 359 | if Result then 360 | begin 361 | AGroupProject.FileName := AFileName; 362 | 363 | LXMLDocument := CreateOleObject('Msxml2.DOMDocument'); 364 | try 365 | LXMLDocument.Async := False; 366 | LXMLDocument.ResolveExternals := False; 367 | LXMLDocument.Load(AFileName); 368 | if LXMLDocument.ParseError.ErrorCode <> 0 then 369 | begin 370 | TryShowErrorFmt(CustomMessage('RADStudioProjectErrorParsingGroupProject'), [AFileName, IntToStr(LXMLDocument.ParseError.ErrorCode), IntToStr(LXMLDocument.ParseError.Line), IntToStr(LXMLDocument.ParseError.LinePos), LXMLDocument.ParseError.Reason]); 371 | Result := False; 372 | Exit; 373 | end; 374 | 375 | // Items 376 | LXMLNodeList := LXMLDocument.SelectNodes('/Project/ItemGroup/BuildGroupProject[@Include and Enabled="True"]'); 377 | AGroupProject.Items := []; 378 | for I := 0 to LXMLNodeList.Length-1 do 379 | begin 380 | if TryGetXMLNodeAttribute(LXMLNodeList.Item[I], 'Include', LAttributeValue) then 381 | begin 382 | LAttributeValue := ExtractFilePath(AGroupProject.FileName) + LAttributeValue; 383 | if TryStrToProjectConfigs(ReadXMLNodeText(LXMLNodeList.Item[I], 'Configurations', ''), LItem.Configs) and 384 | TryStrToProjectPlatforms(ReadXMLNodeText(LXMLNodeList.Item[I], 'Platforms', ''), LItem.Platforms) and 385 | TryLoadRADStudioProject(LAttributeValue, LItem.Project) then 386 | begin 387 | SetArrayLength(AGroupProject.Items, GetArrayLength(AGroupProject.Items) + 1); 388 | AGroupProject.Items[GetArrayLength(AGroupProject.Items) - 1] := LItem; 389 | end; 390 | end; 391 | end; 392 | //Sort Projects inside a Group Project by Requires Dcu count 393 | //AGroupProject.Items := _SortGroupProjectItems(AGroupProject.Items); 394 | except 395 | TryShowErrorFmt(CustomMessage('RADStudioProjectErrorUnexpectedParsingGroupProject'), [AFileName, GetExceptionMessage]); 396 | Result := False; 397 | end; 398 | end; 399 | end; 400 | 401 | function TryLoadRADStudioProject(const AFileName: string; out AProject: TRADStudioProject): Boolean; 402 | var 403 | LPlatform: TProjectPlatform; 404 | LXMLNodeList: Variant; 405 | LXMLDocument: Variant; 406 | LText: string; 407 | I: Integer; 408 | begin 409 | Result := FileExists(AFileName); 410 | if Result then 411 | begin 412 | AProject.FileName := AFileName; 413 | 414 | LXMLDocument := CreateOleObject('Msxml2.DOMDocument'); 415 | try 416 | LXMLDocument.Async := False; 417 | LXMLDocument.ResolveExternals := False; 418 | LXMLDocument.Load(AFileName); 419 | if LXMLDocument.ParseError.ErrorCode <> 0 then 420 | begin 421 | TryShowErrorFmt(CustomMessage('RADStudioProjectErrorParsingProject'), [AFileName, IntToStr(LXMLDocument.ParseError.ErrorCode), IntToStr(LXMLDocument.ParseError.Line), IntToStr(LXMLDocument.ParseError.LinePos), LXMLDocument.ParseError.Reason]); 422 | Result := False; 423 | Exit; 424 | end; 425 | 426 | // IsPackage 427 | AProject.IsPackage := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup/AppType', '') = 'Package'; 428 | 429 | // ProjectVersion 430 | AProject.ProjectVersion := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup/ProjectVersion', ''); 431 | 432 | // IsInstallable 433 | AProject.IsInstallable := not StrToBoolDef(ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/RuntimeOnlyPackage', ''), False); 434 | 435 | // IsDesignOnly 436 | AProject.IsDesignOnly := StrToBoolDef(ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/DesignOnlyPackage', ''), False); 437 | 438 | // Personality 439 | LText := ReadXMLNodeText(LXMLDocument, '/Project/ProjectExtensions/Borland.Personality', ''); 440 | if SameText(LText, 'Delphi.Personality.12') then 441 | AProject.Personality := ppDelphi 442 | else if SameText(LText, 'CPlusPlusBuilder.Personality.12') then 443 | AProject.Personality := ppCBuilder 444 | else 445 | begin 446 | TryShowErrorFmt(CustomMessage('RADStudioProjectErrorParsingProjectUnknownPersonality'), [AFileName, LText]); 447 | Result := False; 448 | Exit; 449 | end; 450 | 451 | // Platforms 452 | LXMLNodeList := LXMLDocument.SelectNodes('/Project/ProjectExtensions/BorlandProject/Platforms/Platform'); 453 | AProject.Platforms := []; 454 | for I := 0 to LXMLNodeList.Length-1 do 455 | begin 456 | if StrToBoolDef(LXMLNodeList.Item[I].Text, False) and TryGetXMLNodeAttribute(LXMLNodeList.Item[I], 'Value', LText) and 457 | TryStrToProjectPlatform(LText, LPlatform) then 458 | begin 459 | Include(AProject.Platforms, LPlatform); 460 | end; 461 | end; 462 | 463 | // SourcePaths & RequiresDCPCount 464 | LXMLNodeList := LXMLDocument.SelectNodes('/Project/ItemGroup/DCCReference/@Include'); 465 | AProject.SourcePaths := []; 466 | AProject.RequiresDCPCount := 0; 467 | for I := 0 to LXMLNodeList.Length-1 do 468 | begin 469 | if EndsWithText(LXMLNodeList.Item[I].Text, '.pas') then 470 | begin 471 | AProject.SourceFiles := AppendString(AProject.SourceFiles, RemoveBackslash(ExpandFileName(AddBackslash(ExtractFilePath(AFileName)) + LXMLNodeList.Item[I].Text)), False); 472 | AProject.SourcePaths := AppendString(AProject.SourcePaths, RemoveBackslash(ExpandFileName(AddBackslash(ExtractFilePath(AFileName)) + ExtractFilePath(LXMLNodeList.Item[I].Text))), False); 473 | end 474 | else if EndsWithText(LXMLNodeList.Item[I].Text, '.dcp') then 475 | AProject.RequiresDCPCount := AProject.RequiresDCPCount + 1; 476 | end; 477 | 478 | AProject.BplOutputPath := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/DCC_BplOutput', ''); 479 | AProject.DcpOutputPath := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/DCC_DcpOutput', ''); 480 | AProject.DCUOutputPath := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/DCC_DcuOutput', ''); 481 | AProject.Description := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/DCC_Description', ''); 482 | AProject.DllSuffix := ReadXMLNodeText(LXMLDocument, '/Project/PropertyGroup[@Condition="''$(Base)''!=''''"]/DllSuffix', ''); 483 | except 484 | TryShowErrorFmt(CustomMessage('RADStudioProjectErrorUnexpectedParsingProject'), [AFileName, GetExceptionMessage]); 485 | Result := False; 486 | end; 487 | end; 488 | end; 489 | 490 | function TryStrToProjectConfig(const AConfigName: string; out AConfig: TProjectConfig): Boolean; 491 | begin 492 | Result := True; 493 | if SameText(AConfigName, 'Debug') then 494 | AConfig := pcDebug 495 | else if SameText(AConfigName, 'Release') then 496 | AConfig := pcRelease 497 | else 498 | Result := False; 499 | end; 500 | 501 | function TryStrToProjectConfigs(const AText: string; out AConfigs: TProjectConfigs): Boolean; 502 | var 503 | LStrings: TArrayOfString; 504 | LConfig: TProjectConfig; 505 | I: Integer; 506 | begin 507 | AConfigs := []; 508 | LStrings := SplitString(AText, ';'); 509 | for I := 0 to GetArrayLength(LStrings)-1 do 510 | begin 511 | if not TryStrToProjectConfig(LStrings[I], LConfig) then 512 | begin 513 | Result := False; 514 | Exit; 515 | end; 516 | Include(AConfigs, LConfig); 517 | end; 518 | Result := AConfigs <> []; 519 | end; 520 | 521 | function TryStrToProjectPlatform(const APlatformName: string; out APlatform: TProjectPlatform): Boolean; 522 | begin 523 | Result := True; 524 | if SameText(APlatformName, 'Win32') then 525 | APlatform := pfWin32 526 | else if SameText(APlatformName, 'Win64') then 527 | APlatform := pfWin64 528 | else if SameText(APlatformName, 'Android') then 529 | APlatform := pfAndroid 530 | else if SameText(APlatformName, 'Android32') then 531 | APlatform := pfAndroid 532 | else if SameText(APlatformName, 'Android64') then 533 | APlatform := pfAndroid64 534 | else if SameText(APlatformName, 'iOSDevice') then 535 | APlatform := pfiOSDevice32 536 | else if SameText(APlatformName, 'iOSDevice32') then 537 | APlatform := pfiOSDevice32 538 | else if SameText(APlatformName, 'iOSDevice64') then 539 | APlatform := pfiOSDevice64 540 | else if SameText(APlatformName, 'iOSSimARM64') then 541 | APlatform := pfiOSSimARM64 542 | else if SameText(APlatformName, 'iOSSimulator') then 543 | APlatform := pfiOSSimulator 544 | else if SameText(APlatformName, 'OSX32') then 545 | APlatform := pfOSX32 546 | else if SameText(APlatformName, 'OSX64') then 547 | APlatform := pfOSX64 548 | else if SameText(APlatformName, 'OSXARM64') then 549 | APlatform := pfOSXARM64 550 | else if SameText(APlatformName, 'Linux64') then 551 | APlatform := pfLinux64 552 | else 553 | Result := False; 554 | end; 555 | 556 | function TryStrToProjectPlatforms(const AText: string; out APlatforms: TProjectPlatforms): Boolean; 557 | var 558 | LStrings: TArrayOfString; 559 | LPlatform: TProjectPlatform; 560 | I: Integer; 561 | begin 562 | APlatforms := []; 563 | LStrings := SplitString(AText, ';'); 564 | for I := 0 to GetArrayLength(LStrings)-1 do 565 | begin 566 | if not TryStrToProjectPlatform(LStrings[I], LPlatform) then 567 | begin 568 | Result := False; 569 | Exit; 570 | end; 571 | Include(APlatforms, LPlatform); 572 | end; 573 | Result := APlatforms <> []; 574 | end; 575 | 576 | // end. 577 | #endif 578 | -------------------------------------------------------------------------------- /Source/Setup.Main.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitSetupMain 2 | #define UnitSetupMain 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit Setup.Main; 18 | 19 | // interface 20 | 21 | // implementation 22 | 23 | // uses 24 | #include ".\RADStudio.inc" 25 | #include ".\RADStudio.Build.inc" 26 | #include ".\RADStudio.Project.inc" 27 | #include ".\IO.Utils.inc" 28 | #include ".\String.Utils.inc" 29 | #include ".\Setup.Pages.inc" 30 | #include ".\Setup.Style.inc" 31 | #include ".\Setup.Utils.inc" 32 | 33 | type 34 | TGetBuildCustomParamEvent = function(): string; 35 | TTryPrepareProjectInstallationEvent = function(var AProjectItem: TRADStudioGroupProjectItem; const AInfo: TRADStudioInfo): Boolean; 36 | TTryPrepareProjectUninstallationEvent = function(var AProjectItem: TRADStudioGroupProjectItem; const AInfo: TRADStudioInfo): Boolean; 37 | 38 | /// [Event] Called to perform custom pre-install and post-install tasks 39 | procedure CurStepChanged(ACurStep: TSetupStep); forward; 40 | /// [Event] Called to perform custom pre-uninstall and post-uninstall tasks 41 | procedure CurUninstallStepChanged(ACurUninstallStep: TUninstallStep); forward; 42 | /// Get the default installation directory 43 | function GetDefaultDirName(AParam: string): string; forward; 44 | /// [Event] First event, triggered when setup initialized just in installation mode 45 | function InitializeSetup: Boolean; forward; 46 | /// [Event] Triggered when initialize wizard (after InitializeSetup) 47 | procedure InitializeWizard; forward; 48 | /// Install the packages 49 | function InstallPackages(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects; const ABeforeProjectBuild: TBeforeProjectBuildFunc): Boolean; forward; 50 | /// Check if the setup can create the uninstall registry key to be able to uninstall in windows settings. This reg key can be disabled by executing the setup with the parameter /CreateUninstallRegKey=no 51 | function NeedsUninstallRegKey: Boolean; forward; 52 | /// [Event] Called to determine whether or not a particular page should be shown at all 53 | function ShouldSkipPage(APageID: Integer): Boolean; forward; 54 | /// Uninstall the packages 55 | function UninstallPackages(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects): Boolean; forward; 56 | 57 | var 58 | FGroupProjects: TRADStudioGroupProjects; 59 | FMaxVersionInGroupProjects: TRADStudioVersion; 60 | FOnBeforeProjectBuild: TBeforeProjectBuildFunc; 61 | FOnGetBuildCustomParam: TGetBuildCustomParamEvent; 62 | FOnTryExtractPreBuildObjects: TTryExtractPreBuildObjectsProc; 63 | FOnTryPrepareProjectInstallation: TTryPrepareProjectInstallationEvent; 64 | FOnTryPrepareProjectUninstallation: TTryPrepareProjectUninstallationEvent; 65 | FRADStudioInfos: TRADStudioInfos; 66 | 67 | // implementation 68 | 69 | /// Make project files (dproj, dpr, groupproj) for versions supported 70 | procedure _MakeProjectsForVersionsSupported(var AGroupProjects: TRADStudioGroupProjects; const ARADStudioInfos: TRADStudioInfos; const AMaxVersionOfficiallySupported: TRADStudioVersion); forward; 71 | /// Check if needs directory page by checking the define FilesEmbedded 72 | function _NeedsDirPage: Boolean; forward; 73 | 74 | procedure CurStepChanged(ACurStep: TSetupStep); 75 | var 76 | LSelectedRADStudioVersions: TRADStudioInfos; 77 | begin 78 | case ACurStep of 79 | ssInstall: 80 | begin 81 | LSelectedRADStudioVersions := GetSelectedRADStudioVersions; 82 | Log(Format('Start installation at folder "%s"...', [WizardDirValue])); 83 | #ifdef FilesEmbedded 84 | ReplaceRootPathOfRADStudioGroupProjects(ExpandConstant('{tmp}\') + '{app}', ExpandConstant('{app}'), FGroupProjects); 85 | #endif 86 | SetAbsolutePathsInRADStudioGroupProjects(ExpandConstant('{app}'), FGroupProjects); 87 | if IsUpgrade then 88 | begin 89 | WizardForm.StatusLabel.Caption := CustomMessage('SetupMainUninstallingDetectedVersion'); 90 | if NeedsUninstallRegKey then 91 | begin 92 | if (not IsVerySilent) and HaveRADStudioInstanceRunning then 93 | begin 94 | TryShowErrorEx(CustomMessage('SetupMainUninstallAbortedToCloseRADStudioInstance'), False); 95 | Abort; 96 | end; 97 | if not TryUninstallCurrentVersion then 98 | begin 99 | TryShowErrorFmt(CustomMessage('SetupMainCouldNotUninstallDetectedVersion'), ['{#LibraryName}']); 100 | Abort; 101 | end; 102 | end; 103 | end; 104 | WizardForm.StatusLabel.Caption := CustomMessage('SetupMainUninstallingFromGetIt'); 105 | TryRemoveFromGetIt(LSelectedRADStudioVersions, '{#LibraryName}'); 106 | WizardForm.StatusLabel.Caption := CustomMessage('SetupMainUninstallingPackages'); 107 | if not UninstallPackages(LSelectedRADStudioVersions, FGroupProjects) then 108 | begin 109 | TryShowError(CustomMessage('SetupMainCouldNotUninstallPackages')); 110 | Abort; 111 | end; 112 | end; 113 | ssPostInstall: 114 | begin 115 | LSelectedRADStudioVersions := GetSelectedRADStudioVersions; 116 | if GetArrayLength(LSelectedRADStudioVersions) <> 0 then 117 | begin 118 | Log('Start installation post extraction files...'); 119 | #ifdef FilesEmbedded 120 | CopyDirectory(ExpandConstant('{tmp}\') +'{app}\{#LibraryPackagesFolder}', ExpandConstant('{app}\') + '{#LibraryPackagesFolder}', False); 121 | #endif 122 | if not InstallPackages(GetSelectedRADStudioVersions, FGroupProjects, FOnBeforeProjectBuild) then 123 | Abort; 124 | if HaveRADStudioInstanceRunning and not IsSilent then 125 | ShowMessage(CustomMessage('SetupMainInstallationSuccesfullyRestartRADStudio')); 126 | end; 127 | end; 128 | else 129 | end; 130 | end; 131 | 132 | procedure CurUninstallStepChanged(ACurUninstallStep: TUninstallStep); 133 | begin 134 | case ACurUninstallStep of 135 | usUninstall: ; 136 | usPostUninstall: 137 | begin 138 | SetAbsolutePathsInRADStudioGroupProjects(ExpandConstant('{app}'), FGroupProjects); 139 | if not UninstallPackages(FRADStudioInfos, FGroupProjects) then 140 | begin 141 | TryShowError(CustomMessage('SetupMainCouldNotUninstallPackages')); 142 | Abort; 143 | end; 144 | end; 145 | else 146 | end; 147 | end; 148 | 149 | function GetDefaultDirName(AParam: string): string; 150 | begin 151 | if _NeedsDirPage then 152 | Result := ExpandConstant('{userdocs}\{#LibraryName}') 153 | else 154 | Result := GetCurrentDir; 155 | end; 156 | 157 | function InitializeSetup: Boolean; 158 | var 159 | LPackagesPath: string; 160 | begin 161 | Result := IsVerySilent or (not HaveRADStudioInstanceRunning); 162 | if not Result then 163 | begin 164 | TryShowMessage(CustomMessage('SetupMainInstallAbortedToCloseRADStudioInstance')); 165 | Exit; 166 | end; 167 | LPackagesPath := AddBackslash('{#LibraryPackagesFolder}'); 168 | #ifdef FilesEmbedded 169 | LPackagesPath := AddBackslash(CombinePath('{app}', LPackagesPath)); 170 | ExtractTemporaryFiles(LPackagesPath + '*'); 171 | LPackagesPath := ExpandConstant('{tmp}\') + LPackagesPath; 172 | #else 173 | LPackagesPath := CombinePath(GetCurrentDir, LPackagesPath); 174 | #endif 175 | Result := TryGetRADStudioGroupProjectsFromPath(LPackagesPath, FGroupProjects); 176 | if Result then 177 | begin 178 | FRADStudioInfos := GetRADStudioInfosSupportedByGroupProjects(FGroupProjects); 179 | TryGetMaxRADStudioVersionInGroupProjects(FGroupProjects, FMaxVersionInGroupProjects); 180 | Result := GetArrayLength(FRADStudioInfos) > 0; 181 | if Result then 182 | _MakeProjectsForVersionsSupported(FGroupProjects, FRADStudioInfos, FMaxVersionInGroupProjects) 183 | else 184 | TryShowError(CustomMessage('SetupMainErrorNoRADStudioVersionAvailable')); 185 | end 186 | else 187 | TryShowError(CustomMessage('SetupMainErrorFailedToGetGroupProjects')); 188 | end; 189 | 190 | // Uninstall initialization 191 | function InitializeUninstall: Boolean; 192 | begin 193 | Result := IsVerySilent or (not HaveRADStudioInstanceRunning); 194 | if not Result then 195 | begin 196 | TryShowMessage(CustomMessage('SetupMainUninstallAbortedToCloseRADStudioInstance')); 197 | Exit; 198 | end; 199 | Result := TryGetRADStudioGroupProjectsFromPath(AddBackslash(CombinePath(ExpandConstant('{app}'), '{#LibraryPackagesFolder}')), FGroupProjects); 200 | if Result then 201 | begin 202 | FRADStudioInfos := GetRADStudioInfosSupportedByGroupProjects(FGroupProjects); 203 | TryGetMaxRADStudioVersionInGroupProjects(FGroupProjects, FMaxVersionInGroupProjects); 204 | end 205 | else 206 | TryShowError(CustomMessage('SetupMainErrorFailedToGetGroupProjects')); 207 | end; 208 | 209 | // Create wizard custom pages 210 | procedure InitializeWizard; 211 | begin 212 | CreateRADStudioVersionsChoicePage(wpWelcome, FRADStudioInfos, FMaxVersionInGroupProjects); 213 | WizardForm.LicenseAcceptedRadio.Checked := True; 214 | end; 215 | 216 | function InstallPackages(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects; 217 | const ABeforeProjectBuild: TBeforeProjectBuildFunc): Boolean; 218 | var 219 | I, J, K: Integer; 220 | LInfo: TRADStudioInfo; 221 | LProject: TRADStudioProject; 222 | LVersion: TRADStudioVersion; 223 | 224 | LBplFileName: string; 225 | LProjectDir: string; 226 | LBplPrj32Dir: string; 227 | LBplPrj64Dir: string; 228 | LBplPrj64FileName: string; 229 | 230 | LBplOutputPath: string; 231 | 232 | LRadStudioCommon32Dir: string; 233 | LRadStudioCommon64Dir: string; 234 | LRadStudioCommon32FileName: string; 235 | LRadStudioCommon64FileName: string; 236 | LSearchPath: string; 237 | LDcpFileName: string; 238 | LPlatform: TProjectPlatform; 239 | LCustomParam: string; 240 | LBuilt: Boolean; 241 | begin 242 | Log('Setup.Main.InstallPackages: Starting...'); 243 | WizardForm.ProgressGauge.Min := 0; 244 | WizardForm.ProgressGauge.Max := GetTryBuildRADStudioPackagesSteps(ARADStudioInfos, AGroupProjects) + 1; 245 | WizardForm.ProgressGauge.Position := 0; 246 | if FOnGetBuildCustomParam <> nil then 247 | LCustomParam := FOnGetBuildCustomParam() 248 | else 249 | LCustomParam := ''; 250 | Result := TryBuildRADStudioPackages(ARADStudioInfos, AGroupProjects, LCustomParam, FOnBeforeProjectBuild, FOnTryExtractPreBuildObjects); 251 | if Result then 252 | begin 253 | WizardForm.StatusLabel.Caption := CustomMessage('SetupMainInstallingPackages'); 254 | try 255 | for I := 0 to GetArrayLength(ARADStudioInfos) - 1 do 256 | begin 257 | LInfo := ARADStudioInfos[I]; 258 | if LInfo.Status in [riNotFound, riNeedOpenFirst] then 259 | Continue; 260 | Log(Format('Setup.Main.InstallPackages: Starting installation in %s...', [LInfo.Version.Name])); 261 | for J := 0 to GetArrayLength(AGroupProjects) - 1 do 262 | begin 263 | for K := GetArrayLength(AGroupProjects[J].Items) - 1 downto 0 do 264 | begin 265 | LProject := AGroupProjects[J].Items[K].Project; 266 | if TryGetRADStudioVersionOfProject(LProject, LVersion) and (CompareRADStudioVersions(LVersion, LInfo.Version) = 0) then 267 | begin 268 | LVersion := LInfo.Version; 269 | Log(Format('Setup.Main.InstallPackages: Starting installation of package "%s" in "%s"...', [LProject.FileName, LVersion.Name])); 270 | 271 | if (FOnTryPrepareProjectInstallation <> nil) and 272 | not FOnTryPrepareProjectInstallation(AGroupProjects[J].Items[K], LInfo) then 273 | begin 274 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1']); 275 | Result := False; 276 | Exit; 277 | end; 278 | LProject := AGroupProjects[J].Items[K].Project; 279 | 280 | LRadStudioCommon64Dir := GetRADStudioCommonBplDir(LInfo, pfWin64); 281 | LRadStudioCommon32Dir := GetRADStudioCommonBplDir(LInfo, pfWin32); 282 | 283 | LProjectDir := ExtractFilePath(LProject.FileName); 284 | LBplOutputPath := LProject.BplOutputPath; 285 | if not SameText(LProject.BplOutputPath, LProjectDir) then 286 | begin 287 | // The Bpl is built into a specific Project Folder: copy to RadStudioCommonBpl 288 | if not TryGetRADStudioProjectBplOutputFileName(LProject, LProject.DllSuffix, LBplFileName) then 289 | begin 290 | TryShowErrorFmt(CustomMessage('SetupMainCouldNotDetectProjectBplOutputFileName'), [ExtractFileName(LProject.FileName), LVersion.Name]); 291 | Result := False; 292 | Exit; 293 | end; 294 | // The Bpl file is built in Project folder: copy the bpl file to RadStudioCommonBplDir 295 | //Copy always the 32 bit BPL file 296 | if (LRadStudioCommon32Dir <> '') then 297 | begin 298 | CopyFileToDir(LBplFileName, LRadStudioCommon32Dir); 299 | // Registering Bpl 32 Bit 300 | if LProject.IsInstallable then 301 | begin 302 | if not TryRegisterRADStudioBpl(LVersion, pfWin32, LBplFileName, LProject.Description) then 303 | begin 304 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '3']); 305 | Result := False; 306 | Exit; 307 | end; 308 | end; 309 | end; 310 | //Copy the 64 bit BPL file only if exists 311 | LBplPrj64FileName := ExpandProjectPath(LBplFileName, LInfo.BuildConfig, pfWin64); 312 | if (pfWin64 in LProject.Platforms) and (LRadStudioCommon64Dir <> '') then 313 | begin 314 | CopyFileToDir(LBplPrj64FileName, LRadStudioCommon64Dir); 315 | // Registering Bpl 64 Bit 316 | if LProject.IsInstallable then 317 | begin 318 | if not TryRegisterRADStudioBpl(LVersion, pfWin64, LBplFileName, LProject.Description) then 319 | begin 320 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '3']); 321 | Result := False; 322 | Exit; 323 | end; 324 | end; 325 | end; 326 | // Registering Bpl 327 | if LProject.IsInstallable then 328 | begin 329 | //Add Path Environment Variable 330 | if not TryAddRADStudioPathEnvVariable(LVersion, RemoveBackslash(ExtractFilePath(LBplFileName))) then 331 | begin 332 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '4']); 333 | Result := False; 334 | Exit; 335 | end; 336 | end; 337 | end 338 | else 339 | begin 340 | // The Bpl file is built in RadStudioCommonBplDir: copy in LibraryPath\${Platform}\${Config}\Bpl 341 | //Acquire only bpl FileName with suffix expanded 342 | if not TryGetRADStudioBplFileName(LProject, LProject.DllSuffix, LBplFileName) then 343 | begin 344 | TryShowErrorFmt(CustomMessage('SetupMainCouldNotDetectProjectBplFileName'), [ExtractFileName(LProject.FileName), LVersion.Name]); 345 | Result := False; 346 | Exit; 347 | end; 348 | //Check if the file is Built before proceeding to Installation 349 | LBuilt := True; 350 | if FOnBeforeProjectBuild <> nil then 351 | LBuilt := FOnBeforeProjectBuild(LProject, LPlatform, LInfo); 352 | if not LBuilt then 353 | Continue; 354 | LRadStudioCommon32FileName := AddBackSlash(LRadStudioCommon32Dir) + LBplFileName; 355 | if not FileExists(LRadStudioCommon32FileName) then 356 | begin 357 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [LRadStudioCommon32FileName, LVersion.Name, '2']); 358 | Result := False; 359 | Exit; 360 | end 361 | else 362 | begin 363 | //Copy the 32 bit BPL file from RadStudioCommonBplDir Folder to Project folder 364 | LBplPrj32Dir := ExpandProjectPath(LProjectDir+'$(Platform)\$(Config)\Bpl', LInfo.BuildConfig, pfWin32); 365 | if (not LProject.IsDesignOnly) and (LRadStudioCommon32Dir <> '') then 366 | CopyFileToDir(LRadStudioCommon32FileName, LBplPrj32Dir); 367 | // Registering 32Bit Bpl 368 | if LProject.IsInstallable then 369 | begin 370 | if not TryRegisterRADStudioBpl(LVersion, pfWin32, LRadStudioCommon32FileName, LProject.Description) then 371 | begin 372 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '3']); 373 | Result := False; 374 | Exit; 375 | end; 376 | end; 377 | end; 378 | //Copy the 64 bit BPL file only if exists 379 | LRadStudioCommon64FileName := AddBackSlash(LRadStudioCommon64Dir) + LBplFileName; 380 | if FileExists(LRadStudioCommon64FileName) and (pfWin64 in LProject.Platforms) then 381 | begin 382 | LBplPrj64Dir := ExpandProjectPath(LProjectDir+'$(Platform)\$(Config)\Bpl', LInfo.BuildConfig, pfWin64); 383 | CopyFileToDir(LRadStudioCommon64FileName, LBplPrj64Dir); 384 | // Registering 64Bit Bpl 385 | if LProject.IsInstallable and (LBplPrj64Dir <> '') then 386 | begin 387 | if not TryRegisterRADStudioBpl(LVersion, pfWin64, LRadStudioCommon64FileName, LProject.Description) then 388 | begin 389 | TryShowErrorFmt(CustomMessage('SetupMainFailedToInstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '3']); 390 | Result := False; 391 | Exit; 392 | end; 393 | end; 394 | end; 395 | end; 396 | 397 | // Adding search paths of Sources from LProject.SourcePaths at the Bottom 398 | for LPlatform := LowProjectPlatform to HighProjectPlatform do 399 | begin 400 | if (not (LPlatform in LProject.Platforms)) or (not CheckIfRADStudioSupportsPlatform(LInfo, LPlatform)) then 401 | Continue; 402 | if LPlatform in GetPlatformsAllowedToBuild(LInfo) then 403 | begin 404 | if Length(LProject.SourcePaths) > 0 then 405 | begin 406 | LSearchPath := JoinStrings(LProject.SourcePaths, ';', False); 407 | //Add Source Search Path on Top from second position 408 | TryAddRADStudioLibrarySearchPath(LVersion, LPlatform, LSearchPath, 1); 409 | end; 410 | // Adding search paths, from LProject.DCUOutputPath at position before first Source Path 411 | LDcpFileName := GetRADStudioProjectDcpFileName(LProject); 412 | LDcpFileName := AddBackSlash(GetRADStudioCommonDcpDir(LInfo, LPlatform)) + LDcpFileName; 413 | if FileExists(LDcpFileName) then 414 | begin 415 | LSearchPath := ExpandProjectPath(LProject.DCUOutputPath, LInfo.BuildConfig, LPlatform); 416 | //Add Binary Search Path on Top in first position 417 | TryAddRADStudioLibrarySearchPath(LVersion, LPlatform, LSearchPath, 0); 418 | end; 419 | end; 420 | end; 421 | end; 422 | end; 423 | end; 424 | end; 425 | finally 426 | if not Result then 427 | begin 428 | WizardForm.StatusLabel.Caption := CustomMessage('SetupMainRevertingPackagesInstallationAfterFailure'); 429 | Log(CustomMessage('SetupMainRevertingPackagesInstallationAfterFailure')); 430 | UninstallPackages(ARADStudioInfos, AGroupProjects); 431 | end; 432 | end; 433 | end; 434 | WizardForm.ProgressGauge.Position := WizardForm.ProgressGauge.Max; 435 | end; 436 | 437 | procedure _MakeProjectsForVersionsSupported(var AGroupProjects: TRADStudioGroupProjects; 438 | const ARADStudioInfos: TRADStudioInfos; const AMaxVersionOfficiallySupported: TRADStudioVersion); 439 | var 440 | I, J, K, L, M: Integer; 441 | LNewGroupProject: TRADStudioGroupProject; 442 | LNewPath: string; 443 | LFiles: TArrayOfString; 444 | begin 445 | for I := 0 to GetArrayLength(ARADStudioInfos) - 1 do 446 | begin 447 | if CompareRADStudioVersions(ARADStudioInfos[I].Version, AMaxVersionOfficiallySupported) > 0 then 448 | begin 449 | for J := 0 to GetArrayLength(AGroupProjects) - 1 do 450 | begin 451 | if ContainsString(SplitString(AGroupProjects[J].FileName, '\'), AMaxVersionOfficiallySupported.Name, False) then 452 | begin 453 | LNewPath := ExtractFilePath(ReplaceFolderNameInPath(AGroupProjects[J].FileName, AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False)); 454 | if CopyDirectory(ExtractFilePath(AGroupProjects[J].FileName), LNewPath, True) then 455 | begin 456 | LFiles := GetFiles(LNewPath, '*', soAllDirectories); 457 | for K := 0 to GetArrayLength(LFiles) - 1 do 458 | ReplaceStringInFile(LFiles[K], AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 459 | LNewGroupProject := CopyRADStudioGroupProject(AGroupProjects[J]); 460 | LNewGroupProject.FileName := ReplaceFolderNameInPath(LNewGroupProject.FileName, AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 461 | for L := 0 to GetArrayLength(LNewGroupProject.Items) - 1 do 462 | begin 463 | LNewGroupProject.Items[L].Project.FileName := ReplaceFolderNameInPath(LNewGroupProject.Items[L].Project.FileName, AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 464 | ReplaceStringInFile(LNewGroupProject.Items[L].Project.FileName, 465 | Format('%s', [LNewGroupProject.Items[L].Project.ProjectVersion]), 466 | Format('%s', [ARADStudioInfos[I].Version.MaxDprojVersion]), False); 467 | LNewGroupProject.Items[L].Project.ProjectVersion := ARADStudioInfos[I].Version.MaxDprojVersion; 468 | LNewGroupProject.Items[L].Project.BplOutputPath := ReplaceFolderNameInPath(LNewGroupProject.Items[L].Project.BplOutputPath, AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 469 | LNewGroupProject.Items[L].Project.DcpOutputPath := ReplaceFolderNameInPath(LNewGroupProject.Items[L].Project.DcpOutputPath, AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 470 | LNewGroupProject.Items[L].Project.DCUOutputPath := ReplaceFolderNameInPath(LNewGroupProject.Items[L].Project.DCUOutputPath, AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 471 | for M := 0 to GetArrayLength(LNewGroupProject.Items[L].Project.SourcePaths) - 1 do 472 | LNewGroupProject.Items[L].Project.SourcePaths[M] := ReplaceFolderNameInPath(LNewGroupProject.Items[L].Project.SourcePaths[M], AMaxVersionOfficiallySupported.Name, ARADStudioInfos[I].Version.Name, False); 473 | end; 474 | SetArrayLength(AGroupProjects, GetArrayLength(AGroupProjects) + 1); 475 | AGroupProjects[GetArrayLength(AGroupProjects) - 1] := LNewGroupProject; 476 | end; 477 | end; 478 | end; 479 | end; 480 | end; 481 | 482 | for I := 0 to GetArrayLength(AGroupProjects) - 1 do 483 | for J := 0 to GetArrayLength(AGroupProjects[I].Items) - 1 do 484 | Log(Format('_MakeProjectsForVersionsSupported: f "%s" g "%s"...', [AGroupProjects[I].Items[J].Project.FileName, AGroupProjects[I].FileName])); 485 | end; 486 | 487 | function _NeedsDirPage: Boolean; 488 | begin 489 | #ifdef FilesEmbedded 490 | Result := True 491 | #else 492 | Result := False; 493 | #endif 494 | end; 495 | 496 | function NeedsUninstallRegKey: Boolean; 497 | begin 498 | #ifdef FilesEmbedded 499 | Result := StrToBoolDef(ExpandConstant('{param:CreateUninstallRegKey|yes}'), True); 500 | #else 501 | Result := False; 502 | #endif 503 | end; 504 | 505 | function ShouldSkipPage(APageID: Integer): Boolean; 506 | begin 507 | Result := (APageID = wpSelectDir) and not _NeedsDirPage; 508 | end; 509 | 510 | function UninstallPackages(const ARADStudioInfos: TRADStudioInfos; const AGroupProjects: TRADStudioGroupProjects): Boolean; 511 | var 512 | I, J, K, L: Integer; 513 | LBplFileName, LOldBplFileName, LDcpFileName: string; 514 | LConfig: TProjectConfig; 515 | LFileName, LProjectDir: string; 516 | LInfo: TRADStudioInfo; 517 | LProject: TRADStudioProject; 518 | LVersion: TRADStudioVersion; 519 | LPlatform: TProjectPlatform; 520 | LReleaseSearchPath: string; 521 | LDebugSearchPath: string; 522 | LSearchPath: string; 523 | LRadStudioCommon32BplDir: string; 524 | LRadStudioCommon64BplDir: string; 525 | LRadStudioCommon32DcpDir: string; 526 | LRadStudioCommon64DcpDir: string; 527 | LBplOutputPath: string; 528 | LRadStudioCommon32FileName: string; 529 | LRadStudioCommon64FileName: string; 530 | begin 531 | Result := True; 532 | Log('Setup.Main.UninstallPackages: Starting...'); 533 | for I := 0 to GetArrayLength(ARADStudioInfos) - 1 do 534 | begin 535 | LInfo := ARADStudioInfos[I]; 536 | if LInfo.Status in [riNotFound, riNeedOpenFirst] then 537 | Continue; 538 | 539 | LRadStudioCommon64BplDir := GetRADStudioCommonBplDir(LInfo, pfWin64); 540 | LRadStudioCommon32BplDir := GetRADStudioCommonBplDir(LInfo, pfWin32); 541 | LRadStudioCommon64DcpDir := GetRADStudioCommonDcpDir(LInfo, pfWin64); 542 | LRadStudioCommon32DcpDir := GetRADStudioCommonDcpDir(LInfo, pfWin32); 543 | for J := 0 to GetArrayLength(AGroupProjects) - 1 do 544 | begin 545 | for K := 0 to GetArrayLength(AGroupProjects[J].Items) - 1 do 546 | begin 547 | LProject := AGroupProjects[J].Items[K].Project; 548 | if TryGetRADStudioVersionOfProject(LProject, LVersion) and (CompareRADStudioVersions(LVersion, LInfo.Version) = 0) then 549 | begin 550 | LVersion := LInfo.Version; 551 | Log(Format('Setup.Main.UninstallPackages: Starting uninstallation of package "%s" in "%s"...', [LProject.FileName, LVersion.Name])); 552 | 553 | if TryGetRADStudioBplFileName(LProject, LProject.DllSuffix, LBplFileName) then 554 | begin 555 | //Delete bpl files in RADStudioCommonBplDir 556 | DeleteFile(CombinePath(LRadStudioCommon32BplDir, ExtractFileName(LBplFileName))); 557 | DeleteFile(CombinePath(LRadStudioCommon64BplDir, ExtractFileName(LBplFileName))); 558 | end; 559 | 560 | //Delete dcp files in RADStudioCommonDcpDir 32bit 561 | LDcpFileName := GetRADStudioProjectDcpFileName(LProject); 562 | DeleteFile(CombinePath(LRadStudioCommon32DcpDir, ExtractFileName(LDcpFileName))); 563 | DeleteFile(CombinePath(LRadStudioCommon64DcpDir, ExtractFileName(LDcpFileName))); 564 | 565 | if TryGetRADStudioBplFileName(LProject, LInfo.Version.OldLibSuffix, LOldBplFileName) then 566 | begin 567 | if (LOldBplFileName <> LBplFileName) then 568 | begin 569 | //Delete bpl with old suffix (eg.D10_3) files in RADStudioCommonBplDir if different of Actual 570 | if LRadStudioCommon32BplDir <> '' then 571 | DeleteFile(CombinePath(LRadStudioCommon32BplDir, ExtractFileName(LOldBplFileName))); 572 | if LRadStudioCommon64BplDir <> '' then 573 | DeleteFile(CombinePath(LRadStudioCommon64BplDir, ExtractFileName(LOldBplFileName))); 574 | end; 575 | end; 576 | 577 | if TryGetRADStudioBplFileName(LProject, '_'+LInfo.Version.OldLibSuffix, LOldBplFileName) then 578 | begin 579 | if (LOldBplFileName <> LBplFileName) then 580 | begin 581 | //Delete bpl with old suffix (eg._D10_3) files in RADStudioCommonBplDir if different of Actual 582 | if LRadStudioCommon32BplDir <> '' then 583 | DeleteFile(CombinePath(LRadStudioCommon32BplDir, ExtractFileName(LOldBplFileName))); 584 | if LRadStudioCommon64BplDir <> '' then 585 | DeleteFile(CombinePath(LRadStudioCommon64BplDir, ExtractFileName(LOldBplFileName))); 586 | end; 587 | end; 588 | 589 | LProjectDir := ExtractFilePath(LProject.FileName); 590 | LBplOutputPath := LProject.BplOutputPath; 591 | if not SameText(LProject.BplOutputPath, LProjectDir) then 592 | begin 593 | // The Bpl is built into a specific Project Folder: Unregister this bpl 594 | TryGetRADStudioProjectBplOutputFileName(LProject, LProject.DllSuffix, LBplFileName); 595 | for LConfig := LowProjectConfig to HighProjectConfig do 596 | begin 597 | // Unregistering Bpl 32Bit 598 | LFileName := ExpandProjectPath(LBplFileName, LConfig, pfWin32); 599 | if not TryUnregisterRADStudioBpl(LVersion, pfWin32, LFileName) then 600 | begin 601 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1'])); 602 | //Result := False; 603 | end; 604 | // Unregistering Bpl 64Bit 605 | LFileName := ExpandProjectPath(LBplFileName, LConfig, pfWin64); 606 | if not TryUnregisterRADStudioBpl(LVersion, pfWin64, LFileName) then 607 | begin 608 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1'])); 609 | //Result := False; 610 | end; 611 | end; 612 | end 613 | else 614 | begin 615 | // The Bpl file is built in RadStudioCommonBplDir: copy in LibraryPath\${Platform}\${Config}\Bpl 616 | //Acquire only bpl FileName with suffix expanded 617 | TryGetRADStudioBplFileName(LProject, LProject.DllSuffix, LBplFileName); 618 | LRadStudioCommon32FileName := AddBackSlash(LRadStudioCommon32BplDir) + LBplFileName; 619 | LRadStudioCommon64FileName := AddBackSlash(LRadStudioCommon64BplDir) + LBplFileName; 620 | for LConfig := LowProjectConfig to HighProjectConfig do 621 | begin 622 | // Unregistering Bpl 32Bit 623 | if not TryUnregisterRADStudioBpl(LVersion, pfWin32, LRadStudioCommon32FileName) then 624 | begin 625 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1'])); 626 | //Result := False; 627 | end; 628 | // Unregistering Bpl 64Bit 629 | if not TryUnregisterRADStudioBpl(LVersion, pfWin64, LRadStudioCommon64FileName) then 630 | begin 631 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1'])); 632 | //Result := False; 633 | end; 634 | end; 635 | //Try to unregister old Bpl suffix 636 | TryGetRADStudioBplFileName(LProject, LInfo.Version.OldLibSuffix, LOldBplFileName); 637 | LRadStudioCommon32FileName := AddBackSlash(LRadStudioCommon32BplDir) + LOldBplFileName; 638 | if LOldBplFileName <> LBplFileName then 639 | begin 640 | for LConfig := LowProjectConfig to HighProjectConfig do 641 | begin 642 | // Unregistering Bpl 32Bit 643 | if not TryUnregisterRADStudioBpl(LVersion, pfWin32, LRadStudioCommon32FileName) then 644 | begin 645 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1'])); 646 | end; 647 | // Unregistering Bpl 64Bit 648 | if not TryUnregisterRADStudioBpl(LVersion, pfWin64, LRadStudioCommon64FileName) then 649 | begin 650 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '1'])); 651 | end; 652 | end; 653 | end; 654 | end; 655 | if (FOnTryPrepareProjectUninstallation <> nil) and not FOnTryPrepareProjectUninstallation(AGroupProjects[J].Items[K], LInfo) then 656 | begin 657 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name, '3'])); 658 | Result := False; 659 | end; 660 | LProject := AGroupProjects[J].Items[K].Project; 661 | 662 | // Removing search paths 663 | for LPlatform := LowProjectPlatform to HighProjectPlatform do 664 | begin 665 | if (not (LPlatform in LProject.Platforms)) or (not CheckIfRADStudioSupportsPlatform(LInfo, LPlatform)) then 666 | Continue; 667 | if LPlatform in GetPlatformsAllowedToBuild(LInfo) then 668 | begin 669 | LReleaseSearchPath := ExpandProjectPath(LProject.DCUOutputPath, pcRelease, LPlatform); 670 | LDebugSearchPath := ExpandProjectPath(LProject.DCUOutputPath, pcDebug, LPlatform); 671 | if (not TryRemoveRADStudioLibrarySearchPath(LVersion, LPlatform, LReleaseSearchPath)) or 672 | (not TryRemoveRADStudioLibrarySearchPath(LVersion, LPlatform, LDebugSearchPath)) then 673 | begin 674 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name + ' - ' + GetProjectPlatformName(LPlatform), '4'])); 675 | Result := False; 676 | end; 677 | end; 678 | for L := 0 to GetArrayLength(LProject.SourcePaths) - 1 do 679 | begin 680 | LSearchPath := LProject.SourcePaths[L]; 681 | if not TryRemoveRADStudioLibrarySearchPath(LVersion, LPlatform, LSearchPath) then 682 | begin 683 | Log(FmtMessage(CustomMessage('SetupMainFailedToUninstallPackage'), [ExtractFileName(LProject.FileName), LVersion.Name + ' - ' + GetProjectPlatformName(LPlatform), '5'])); 684 | Result := False; 685 | end; 686 | end; 687 | end; 688 | end; 689 | end; 690 | end; 691 | end; 692 | end; 693 | 694 | // end. 695 | #endif 696 | -------------------------------------------------------------------------------- /Source/Setup.Pages.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitSetupPages 2 | #define UnitSetupPages 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit Setup.Pages; 18 | 19 | // interface 20 | 21 | // uses 22 | #include ".\RADStudio.inc" 23 | 24 | /// Create the RAD Studio versions choise page 25 | procedure CreateRADStudioVersionsChoicePage(const AAfterID: Integer; const ARADStudioInfos: TRADStudioInfos; const AMaxVersionOfficiallySupported: TRADStudioVersion); forward; 26 | /// Get selected RAD Studio versions 27 | function GetSelectedRADStudioVersions: TRADStudioInfos; forward; 28 | 29 | // implementation 30 | 31 | // uses 32 | #include ".\Setup.Utils.inc" 33 | 34 | /// Get selected RAD Studio versions in versions choise page 35 | function _GetSelectedVersions: TRADStudioInfos; forward; 36 | /// On versions choise page click 37 | function _OnRADStudioVersionsPageNextButtonClick(ASender: TWizardPage): Boolean; forward; 38 | 39 | var 40 | _FRADStudioVersionsChoicePage: TInputOptionWizardPage; 41 | _FRADStudioVersionsChoicePageOptions: TRADStudioInfos; 42 | _FSelectedRADStudioVersions: TRADStudioInfos; 43 | 44 | procedure CreateRADStudioVersionsChoicePage(const AAfterID: Integer; const ARADStudioInfos: TRADStudioInfos; const AMaxVersionOfficiallySupported: TRADStudioVersion); 45 | var 46 | I: Integer; 47 | LMinIndexSelected: Integer; 48 | LHasRADStudioVersionsParam: Boolean; 49 | LSubItem: string; 50 | begin 51 | if WizardSilent then 52 | _FSelectedRADStudioVersions := ARADStudioInfos 53 | else 54 | begin 55 | LHasRADStudioVersionsParam := HasParam('/RADStudioVersions'); 56 | _FRADStudioVersionsChoicePageOptions := ARADStudioInfos; 57 | _FRADStudioVersionsChoicePage := CreateInputOptionPage(AAfterID, CustomMessage('SetupPagesRADStudioVersionsChoiceTitle'), '', 58 | FmtMessage(CustomMessage('SetupPagesRADStudioVersionsChoiceMessage'), ['{#LibraryName}']), False, False); 59 | 60 | LMinIndexSelected := GetArrayLength(ARADStudioInfos); 61 | for I := GetArrayLength(ARADStudioInfos) - 1 downto 0 do 62 | begin 63 | if ARADStudioInfos[I].Status in [riToolchainNotSupported, riNormal] then 64 | begin 65 | LMinIndexSelected := I; 66 | if CompareRADStudioVersions(ARADStudioInfos[I].Version, AMaxVersionOfficiallySupported) <= 0 then 67 | Break; 68 | end; 69 | end; 70 | 71 | for I := 0 to GetArrayLength(ARADStudioInfos) - 1 do 72 | begin 73 | case ARADStudioInfos[I].Status of 74 | riNotFound: _FRADStudioVersionsChoicePage.CheckListBox.AddCheckBox(ARADStudioInfos[I].Version.Name, '', 0, False, False, False, False, nil); 75 | riNeedOpenFirst: _FRADStudioVersionsChoicePage.CheckListBox.AddCheckBox(ARADStudioInfos[I].Version.Name, CustomMessage('SetupPagesRADStudioVersionsChoiceAlertNeedOpenFirst'), 0, False, False, False, False, nil); 76 | riToolchainNotSupported, 77 | riNormal: 78 | begin 79 | if CompareRADStudioVersions(ARADStudioInfos[I].Version, AMaxVersionOfficiallySupported) > 0 then 80 | LSubItem := CustomMessage('SetupPagesRADStudioVersionsChoiceUnofficialSupport') 81 | else 82 | LSubItem := ''; 83 | _FRADStudioVersionsChoicePage.CheckListBox.AddCheckBox(ARADStudioInfos[I].Version.Name, LSubItem, 0, LHasRADStudioVersionsParam or (I >= LMinIndexSelected), True, False, False, nil); 84 | end; 85 | else 86 | end; 87 | end; 88 | _FRADStudioVersionsChoicePage.OnNextButtonClick := @_OnRADStudioVersionsPageNextButtonClick; 89 | end; 90 | end; 91 | 92 | function GetSelectedRADStudioVersions: TRADStudioInfos; 93 | begin 94 | Result := _FSelectedRADStudioVersions; 95 | end; 96 | 97 | function _GetSelectedVersions: TRADStudioInfos; 98 | var 99 | I: Integer; 100 | begin 101 | Result := []; 102 | if _FRADStudioVersionsChoicePage <> nil then 103 | begin 104 | for I := 0 to GetArrayLength(_FRADStudioVersionsChoicePageOptions) - 1 do 105 | begin 106 | if _FRADStudioVersionsChoicePage.CheckListBox.ItemEnabled[I] and (_FRADStudioVersionsChoicePage.CheckListBox.State[I] = cbChecked) then 107 | begin 108 | SetArrayLength(Result, GetArrayLength(Result) + 1); 109 | Result[GetArrayLength(Result) - 1] := _FRADStudioVersionsChoicePageOptions[I]; 110 | end; 111 | end; 112 | end; 113 | end; 114 | 115 | function _OnRADStudioVersionsPageNextButtonClick(ASender: TWizardPage): Boolean; 116 | begin 117 | _FSelectedRADStudioVersions := _GetSelectedVersions; 118 | Result := GetArrayLength(_FSelectedRADStudioVersions) <> 0; 119 | if (not Result) and (not IsVerySilent) then 120 | Result := MsgBox(CustomMessage('SetupPagesNoneRADStudioVersionsSelectedMessage'), mbConfirmation, MB_YESNO or MB_DEFBUTTON1) = IDYES; 121 | end; 122 | 123 | // end. 124 | #endif 125 | -------------------------------------------------------------------------------- /Source/Setup.Style.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitSetupStyle 2 | #define UnitSetupStyle 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit Setup.Style; 18 | 19 | // interface 20 | 21 | // implementation 22 | 23 | #ifdef VclStyle 24 | {************************************************************************} 25 | { } 26 | { VCL Styles Plugin for Inno Setup } 27 | { https://github.com/RRUZ/vcl-styles-plugins } 28 | { } 29 | { Copyright (c) 2013-2025 Rodrigo Ruz V. } 30 | { } 31 | { Use of this source code is governed by a MPL 1.1 license that can be } 32 | { found at http://www.mozilla.org/MPL/ } 33 | { } 34 | {************************************************************************} 35 | 36 | // uses 37 | #include ".\Setup.Utils.inc" 38 | 39 | #define _StylesDllName 'Setup.Styles.dll'; 40 | #define _StyleSubDir 'Style' 41 | 42 | /// [External] Load a vcl style in setup 43 | procedure _DllLoadVclStyle(AVclStyleFile: string); external 'LoadVCLStyleW@files:{#_StylesDllName} stdcall delayload setuponly'; 44 | /// [External] Load a vcl style in uninstaller 45 | procedure _DllLoadVclStyleUninstall(AVclStyleFile: string); external 'LoadVCLStyleW@{tmp}\{#_StylesDllName} stdcall delayload uninstallonly'; 46 | /// [External] Unload vcl styles in setup 47 | procedure _DllUnloadVclStyles; external 'UnLoadVCLStyles@files:{#_StylesDllName} stdcall setuponly delayload'; 48 | /// [External] Unload vcl styles in uninstaller 49 | procedure _DllUnloadVclStylesUninstall; external 'UnLoadVCLStyles@{tmp}\{#_StylesDllName} stdcall delayload uninstallonly'; 50 | 51 | var 52 | _FIsUsingVclStyles: Boolean; 53 | 54 | 55 | procedure _SetupStyleDeinitializeSetup; 56 | begin 57 | if _FIsUsingVclStyles then 58 | _DllUnloadVclStyles; 59 | end; 60 | 61 | 62 | procedure _SetupStyleDeinitializeUninstall; 63 | begin 64 | if _FIsUsingVclStyles then 65 | _DllUnloadVclStylesUninstall; 66 | end; 67 | 68 | 69 | function _SetupStyleInitializeSetup: Boolean; 70 | begin 71 | _FIsUsingVclStyles := False; 72 | if not IsVerySilent then 73 | begin 74 | #ifdef FilesEmbedded 75 | ExtractTemporaryFile('{#VclStyle}'); 76 | _DllLoadVclStyle(ExpandConstant('{tmp}\{#VclStyle}')); 77 | #else 78 | _DllLoadVclStyle(CombinePath(GetCurrentDir, '{#SetupFolder}\{#_StyleSubDir}\{#VclStyle}')); 79 | #endif 80 | _FIsUsingVclStyles := True; 81 | end; 82 | Result := True; 83 | end; 84 | 85 | 86 | function _SetupStyleInitializeUninstall: Boolean; 87 | begin 88 | _FIsUsingVclStyles := False; 89 | if (not IsVerySilent) and 90 | FileCopy(ExpandConstant('{app}\{#SetupFolder}\{#_StyleSubDir}\{#_StylesDllName}'), ExpandConstant('{tmp}\{#_StylesDllName}'), False) and 91 | FileExists(CombinePath(ExpandConstant('{app}'), '{#SetupFolder}\{#_StyleSubDir}\{#VclStyle}')) then 92 | begin 93 | _DllLoadVclStyleUninstall(CombinePath(ExpandConstant('{app}'), '{#SetupFolder}\{#_StyleSubDir}\{#VclStyle}')); 94 | _FIsUsingVclStyles := True; 95 | end; 96 | Result := True; 97 | end; 98 | 99 | 100 | procedure _SetupStyleInitializeWizard; 101 | begin 102 | // Fix small issue in inno setup when styles enabled 103 | if _FIsUsingVclStyles then 104 | WizardForm.CancelButton.Top := WizardForm.NextButton.Top; 105 | end; 106 | #endif 107 | 108 | // end. 109 | #endif 110 | -------------------------------------------------------------------------------- /Source/Setup.Utils.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitSetupUtils 2 | #define UnitSetupUtils 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit Setup.Utils; 18 | 19 | // interface 20 | 21 | /// Check if the setup was executed with an specific param 22 | function HasParam(const AParamName: string): Boolean; forward; 23 | /// Check if an app is running by its file name, without path, like 'bds.exe' 24 | function IsAppRunning(const AFileName: string): Boolean; forward; 25 | /// Check if is running in silent mode (/SILENT or /VERYSILENT) 26 | function IsSilent: Boolean; forward; 27 | /// Check if there is already a version of the application installed 28 | function IsUpgrade: Boolean; forward; 29 | /// Check if the installation has been executed with /verysilent parameter 30 | function IsVerySilent: Boolean; forward; 31 | /// Read a single node text and return a default value if not found 32 | function ReadXMLNodeText(const AXMLNode: Variant; const AXPath, ADefaultValue: string): string; forward; 33 | /// Show a message error 34 | procedure ShowError(const AMessage: string); forward; 35 | /// Show a formated message error 36 | procedure ShowErrorFmt(const AMessage: string; const AArgs: TArrayOfString); forward; 37 | /// Show an information message 38 | procedure ShowMessage(const AMessage: string); forward; 39 | /// Try to get the an attribute value of a xml node by the attribute name with case insensitive 40 | function TryGetXMLNodeAttribute(const AXMLNode: Variant; const AAttributeName: string; out AValue: string): Boolean; forward; 41 | /// Try to open a filename in notepad. When in very silent mode, it will fail. 42 | function TryOpenInNotepad(const AFileName: string): Boolean; forward; 43 | /// Try to open the support url defined by #LibrarySupportURL. When in very silent mode, it will fail. 44 | function TryOpenSupportURL: Boolean; forward; 45 | /// Try to open a url. When in very silent mode, it will fail. 46 | function TryOpenURL(const AURL: string): Boolean; forward; 47 | /// Try to show a message error if the installation is not in an error state 48 | function TryShowError(const AMessage: string): Boolean; forward; 49 | /// Try to show a message error if the installation is not in an error state 50 | function TryShowErrorEx(const AMessage: string; const ACanReportIssue: Boolean): Boolean; forward; 51 | /// Try to show a formated message error if the installation is not in an error state 52 | function TryShowErrorFmt(const AMessage: string; const AArgs: TArrayOfString): Boolean; forward; 53 | /// Try to show an information message. It will fail when in very silent mode or in error state 54 | function TryShowMessage(const AMessage: string): Boolean; forward; 55 | /// Try to uninstall the current version 56 | function TryUninstallCurrentVersion: Boolean; forward; 57 | 58 | // implementation 59 | 60 | // uses 61 | #include ".\String.Utils.inc" 62 | 63 | /// Open the setup logs file 64 | procedure _OpenSetupLogsFile; forward; 65 | /// Get the uninstall executable of current version installed in machine. If not found an empty string will be returned. 66 | function _GetUninstallString: string; forward; 67 | /// Initialization method of the unit 68 | procedure _InitializationUnitSetupUtils; forward; 69 | /// Try to remove the uninstall registry of the app 70 | function _TryRemoveUninstallRegKey: Boolean; forward; 71 | 72 | var 73 | _FInitializationUnitSetupUtils: Boolean; 74 | _FIsInErrorState: Boolean; 75 | _FIsVerySilent: Boolean; 76 | 77 | function _GetUninstallString: string; 78 | var 79 | LUninstallRegKey: string; 80 | begin 81 | LUninstallRegKey := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); 82 | Result := ''; 83 | if not RegQueryStringValue(HKEY_LOCAL_MACHINE, LUninstallRegKey, 'UninstallString', Result) then 84 | RegQueryStringValue(HKEY_CURRENT_USER, LUninstallRegKey, 'UninstallString', Result); 85 | end; 86 | 87 | function HasParam(const AParamName: string): Boolean; 88 | var 89 | I: Integer; 90 | LCurrentParam: string; 91 | LSplittedParam: TArrayOfString; 92 | begin 93 | if AParamName <> '' then 94 | begin 95 | for I := 1 to ParamCount do 96 | begin 97 | LCurrentParam := ParamStr(I); 98 | if (Pos('=', LCurrentParam) <> 0) and (Pos('=', AParamName) = 0) then 99 | begin 100 | LSplittedParam := SplitString(LCurrentParam, '='); 101 | if GetArrayLength(LSplittedParam) > 0 then 102 | LCurrentParam := LSplittedParam[0]; 103 | end; 104 | if SameText(LCurrentParam, AParamName) then 105 | begin 106 | Result := True; 107 | Exit; 108 | end; 109 | end; 110 | end; 111 | Result := False; 112 | end; 113 | 114 | procedure _InitializationUnitSetupUtils; 115 | var 116 | I: Integer; 117 | begin 118 | if _FInitializationUnitSetupUtils then 119 | Exit; 120 | _FInitializationUnitSetupUtils := True; 121 | for I := 1 to ParamCount do 122 | Log('Setup.Utils._InitializationUnitSetupUtils: Params[' + InttoStr(I) + ']=' + ParamStr(I)); 123 | _FIsVerySilent := HasParam('/VERYSILENT'); 124 | end; 125 | 126 | function IsAppRunning(const AFileName: string): Boolean; 127 | var 128 | LSWbemLocator: Variant; 129 | LWMIService: Variant; 130 | LWbemObjectSet: Variant; 131 | begin 132 | try 133 | LSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); 134 | if VarIsNull(LSWbemLocator) then 135 | Result := False 136 | else 137 | begin 138 | LWMIService := LSWbemLocator.ConnectServer('.', 'root\CIMV2'); 139 | LWbemObjectSet := LWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process WHERE Name="%s"', [AFileName])); 140 | Result := not VarIsNull(LWbemObjectSet) and (LWbemObjectSet.Count > 0); 141 | end; 142 | except 143 | if SameText(AFileName, 'bds.exe') then 144 | begin 145 | Result := (FindWindowByClassName('TAppBuilder') <> 0) and 146 | (FindWindowByClassName('TPropertyInspector') <> 0) and 147 | (FindWindowByWindowName('Object Inspector') <> 0); 148 | end 149 | else 150 | Result := False; 151 | end; 152 | end; 153 | 154 | function IsSilent: Boolean; 155 | begin 156 | Result := IsVerySilent; 157 | if not Result then 158 | begin 159 | if IsUninstaller then 160 | Result := UninstallSilent 161 | else 162 | Result := WizardSilent; 163 | end; 164 | end; 165 | 166 | function IsUpgrade: Boolean; 167 | begin 168 | Result := _GetUninstallString <> ''; 169 | end; 170 | 171 | function IsVerySilent: Boolean; 172 | begin 173 | _InitializationUnitSetupUtils; 174 | Result := _FIsVerySilent; 175 | end; 176 | 177 | procedure _OpenSetupLogsFile; 178 | begin 179 | if (not IsUninstaller) and (not IsVerySilent) then 180 | TryOpenInNotepad(ExpandConstant(ExpandConstant('{log}'))); 181 | end; 182 | 183 | function ReadXMLNodeText(const AXMLNode: Variant; const AXPath, ADefaultValue: string): string; 184 | var 185 | LXMLNode: Variant; 186 | begin 187 | LXMLNode := AXMLNode.SelectSingleNode(AXPath); 188 | if VarIsClear(LXMLNode) then 189 | Result := ADefaultValue 190 | else 191 | Result := LXMLNode.Text; 192 | end; 193 | 194 | procedure ShowError(const AMessage: string); 195 | var 196 | LIsFirstError: Boolean; 197 | begin 198 | Log('Setup.Utils.ShowError: ' + AMessage); 199 | LIsFirstError := not _FIsInErrorState; 200 | _FIsInErrorState := True; 201 | if not IsVerySilent then 202 | begin 203 | #ifdef LibrarySupportURL 204 | MsgBox(AMessage + CustomMessage('SetupUtilsPleaseReportThiIssue'), mbError, mb_OK); 205 | TryOpenSupportURL; 206 | #else 207 | MsgBox(AMessage, mbError, mb_OK); 208 | #endif 209 | end; 210 | if LIsFirstError then 211 | _OpenSetupLogsFile; 212 | end; 213 | 214 | procedure ShowErrorFmt(const AMessage: string; const AArgs: TArrayOfString); 215 | begin 216 | ShowError(FmtMessage(AMessage, AArgs)); 217 | end; 218 | 219 | procedure ShowMessage(const AMessage: string); 220 | begin 221 | Log('Setup.Utils.ShowMessage: ' + AMessage); 222 | if not IsVerySilent then 223 | MsgBox(AMessage, mbInformation, MB_OK); 224 | end; 225 | 226 | function TryGetXMLNodeAttribute(const AXMLNode: Variant; const AAttributeName: string; out AValue: string): Boolean; 227 | var 228 | I: Integer; 229 | begin 230 | for I := 0 to AXMLNode.Attributes.Length - 1 do 231 | begin 232 | if SameText(AXMLNode.Attributes[I].NodeName, AAttributeName) then 233 | begin 234 | AValue := AXMLNode.Attributes[I].NodeValue; 235 | Result := True; 236 | Exit; 237 | end; 238 | end; 239 | Result := False; 240 | end; 241 | 242 | function TryOpenInNotepad(const AFileName: string): Boolean; 243 | var 244 | LResultCode: Integer; 245 | begin 246 | Log('Setup.Utils.TryOpenInNotepad: ' + AFileName); 247 | Result := (not IsVerySilent) and FileExists(AFileName) and Exec('notepad', '"' + AFileName + '"', '', SW_SHOW, ewNoWait, LResultCode) and (LResultCode = 0); 248 | end; 249 | 250 | function TryOpenSupportURL: Boolean; 251 | begin 252 | Result := TryOpenURL(ExpandConstant('{#LibrarySupportURL}')); 253 | end; 254 | 255 | function TryOpenURL(const AURL: string): Boolean; 256 | var 257 | LResultCode: Integer; 258 | begin 259 | Log('Setup.Utils.TryOpenURL: ' + AURL); 260 | Result := (not IsVerySilent) and (AURL <> '') and ShellExec('open', AURL, '', '', SW_SHOW, ewNoWait, LResultCode) and (LResultCode = 0); 261 | end; 262 | 263 | function _TryRemoveUninstallRegKey: Boolean; 264 | var 265 | LUninstallRegKey: string; 266 | begin 267 | Result := True; 268 | LUninstallRegKey := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); 269 | if RegKeyExists(HKEY_LOCAL_MACHINE, LUninstallRegKey) then 270 | Result := RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, LUninstallRegKey) and Result; 271 | if RegKeyExists(HKEY_CURRENT_USER, LUninstallRegKey) then 272 | Result := RegDeleteKeyIncludingSubkeys(HKEY_CURRENT_USER, LUninstallRegKey) and Result; 273 | end; 274 | 275 | function TryShowError(const AMessage: string): Boolean; 276 | begin 277 | Result := TryShowErrorEx(AMessage, True); 278 | end; 279 | 280 | function TryShowErrorEx(const AMessage: string; const ACanReportIssue: Boolean): Boolean; 281 | var 282 | LIsFirstError: Boolean; 283 | begin 284 | Log('Setup.Utils.TryShowErrorEx: ' + AMessage); 285 | Result := (not _FIsInErrorState) and (not IsVerySilent); 286 | LIsFirstError := not _FIsInErrorState; 287 | _FIsInErrorState := True; 288 | if Result then 289 | begin 290 | #ifdef LibrarySupportURL 291 | if ACanReportIssue then 292 | begin 293 | MsgBox(AMessage + CustomMessage('SetupUtilsPleaseReportThiIssue'), mbError, mb_OK); 294 | TryOpenSupportURL; 295 | end 296 | else 297 | MsgBox(AMessage, mbError, mb_OK); 298 | #else 299 | MsgBox(AMessage, mbError, mb_OK); 300 | #endif 301 | end; 302 | if LIsFirstError and ACanReportIssue then 303 | _OpenSetupLogsFile; 304 | end; 305 | 306 | function TryShowErrorFmt(const AMessage: string; const AArgs: TArrayOfString): Boolean; 307 | begin 308 | case GetArrayLength(AArgs) of 309 | 0: Result := TryShowError(AMessage); 310 | 1: Result := TryShowError(FmtMessage(AMessage, [AArgs[0]])); 311 | 2: Result := TryShowError(FmtMessage(AMessage, [AArgs[0], AArgs[1]])); 312 | 3: Result := TryShowError(FmtMessage(AMessage, [AArgs[0], AArgs[1], AArgs[2]])); 313 | 4: Result := TryShowError(FmtMessage(AMessage, [AArgs[0], AArgs[1], AArgs[2], AArgs[3]])); 314 | 5: Result := TryShowError(FmtMessage(AMessage, [AArgs[0], AArgs[1], AArgs[2], AArgs[3], AArgs[4]])); 315 | 6: Result := TryShowError(FmtMessage(AMessage, [AArgs[0], AArgs[1], AArgs[2], AArgs[3], AArgs[4], AArgs[5]])); 316 | 7: Result := TryShowError(FmtMessage(AMessage, [AArgs[0], AArgs[1], AArgs[2], AArgs[3], AArgs[4], AArgs[5], AArgs[6]])); 317 | else 318 | begin 319 | Log('Setup.Utils.TryShowErrorFmt: Cannot possible to format the message "' + AMessage + '"'); 320 | Result := TryShowError(AMessage); 321 | end; 322 | end; 323 | end; 324 | 325 | function TryShowMessage(const AMessage: string): Boolean; 326 | begin 327 | Log('Setup.Utils.TryShowMessage: ' + AMessage); 328 | Result := (not _FIsInErrorState) and (not IsVerySilent); 329 | if Result then 330 | MsgBox(AMessage, mbInformation, MB_OK); 331 | end; 332 | 333 | function TryUninstallCurrentVersion: Boolean; 334 | var 335 | LUninstallString: string; 336 | LExtraParam: string; 337 | LResultCode: Integer; 338 | begin 339 | LExtraParam := ''; 340 | if IsVerySilent then 341 | LExtraParam := ' /VERYSILENT'; 342 | LUninstallString := _GetUninstallString; 343 | Log('Setup.Utils.TryUninstallCurrentVersion: ' + LUninstallString); 344 | if LUninstallString = '' then 345 | begin 346 | Result := True; 347 | Exit; 348 | end; 349 | LUninstallString := RemoveQuotes(LUninstallString); 350 | if FileExists(LUninstallString) then 351 | Result := (Exec(LUninstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES' + LExtraParam, '', SW_HIDE, ewWaitUntilTerminated, LResultCode) and (LResultCode = 0)) 352 | else 353 | Result := _TryRemoveUninstallRegKey; 354 | end; 355 | 356 | // end. 357 | #endif 358 | -------------------------------------------------------------------------------- /Source/String.Utils.inc: -------------------------------------------------------------------------------- 1 | #ifndef UnitStringUtils 2 | #define UnitStringUtils 3 | 4 | [Code] 5 | {************************************************************************} 6 | { } 7 | { InnoSetup Tools Library for Delphi Components } 8 | { } 9 | { Copyright (c) 2024-2025 Ethea S.r.l. } 10 | { } 11 | { Original Code is Copyright (c) 2021-2025 Skia4Delphi Project. } 12 | { } 13 | { Use of this source code is governed by the MIT license that can be } 14 | { found in the LICENSE file. } 15 | { } 16 | {************************************************************************} 17 | // unit String.Utils; 18 | 19 | // interface 20 | 21 | /// Add a string to the array 22 | function AppendString(const AStrings: TArrayOfString; const ANewString: string; const AAllowDuplicates: Boolean): TArrayOfString; forward; 23 | /// Convert booleans to string in word format (True or False) 24 | function BoolToStr(const AValue: Boolean): string; forward; 25 | /// Compare two versions that are in string format 26 | function CompareVersions(const AVersion1, AVersion2: string): Integer; forward; 27 | /// Check if a string contains in an array of strings 28 | function ContainsString(const AStrings: TArrayOfString; const AValue: string; const ACaseSensitive: Boolean): Boolean; forward; 29 | /// Check if one text ends with another text with case insentive comparison 30 | function EndsWithText(const AText, ASubText: string): Boolean; forward; 31 | /// Insert a string to the array 32 | function InsertString(AIndex: Integer; const AStrings: TArrayOfString; const ANewString: string; const AAllowDuplicates: Boolean): TArrayOfString; forward; 33 | /// Insert a string to the array at index 0 34 | function InsertStringAtBeginning(const AStrings: TArrayOfString; const ANewString: string): TArrayOfString; forward; 35 | /// Concatenates strings into one, separating each string by a delimiter 36 | function JoinStrings(const AStrings: TArrayOfString; const ADelimiter: string; const AJoinEmptyStrings: Boolean): string; forward; 37 | /// Remove all matches of a string in an array 38 | function RemoveString(const AStrings: TArrayOfString; const AValue: string; const ACaseSensitive: Boolean): TArrayOfString; forward; 39 | /// Replace all matches of a string in an array 40 | function ReplaceString(const AStrings: TArrayOfString; const AOldValue, ANewValue: string; const ACaseSensitive, AWholeLine: Boolean): TArrayOfString; forward; 41 | /// Break a string into an array of substrings 42 | function SplitString(AText: string; const ADelimiter: string): TArrayOfString; forward; 43 | /// Check if one text starts with another text with case insentive comparison 44 | function StartsWithText(const AText, ASubText: string): Boolean; forward; 45 | /// Try to convert strings to booleans. If fail, the ADefault value will be returned. 46 | function StrToBoolDef(const AValue: string; const ADefault: Boolean): Boolean; forward; 47 | 48 | // implementation 49 | 50 | function AppendString(const AStrings: TArrayOfString; const ANewString: string; const AAllowDuplicates: Boolean): TArrayOfString; 51 | begin 52 | Result := InsertString(GetArrayLength(AStrings), AStrings, ANewString, AAllowDuplicates); 53 | end; 54 | 55 | function BoolToStr(const AValue: Boolean): string; 56 | begin 57 | if AValue then 58 | Result := 'True' 59 | else 60 | Result := 'False'; 61 | end; 62 | 63 | function CompareVersions(const AVersion1, AVersion2: string): Integer; 64 | var 65 | LVersion1, LVersion2: Int64; 66 | begin 67 | if not StrToVersion(AVersion1, LVersion1) then 68 | RaiseException(FmtMessage('String.Utils.CompareVersions: Invalid version "%1"', [AVersion1])); 69 | if not StrToVersion(AVersion2, LVersion2) then 70 | RaiseException(FmtMessage('String.Utils.CompareVersions: Invalid version "%1"', [AVersion2])); 71 | Result := ComparePackedVersion(LVersion1, LVersion2); 72 | end; 73 | 74 | function ContainsString(const AStrings: TArrayOfString; const AValue: string; const ACaseSensitive: Boolean): Boolean; 75 | var 76 | I: Integer; 77 | begin 78 | Result := True; 79 | if ACaseSensitive then 80 | begin 81 | for I := 0 to GetArrayLength(AStrings) - 1 do 82 | if AStrings[I] = AValue then 83 | Exit; 84 | end 85 | else 86 | begin 87 | for I := 0 to GetArrayLength(AStrings) - 1 do 88 | if SameText(AStrings[I], AValue) then 89 | Exit; 90 | end; 91 | Result := False; 92 | end; 93 | 94 | function EndsWithText(const AText, ASubText: string): Boolean; 95 | var 96 | LSubTextLocation: Integer; 97 | begin 98 | if ASubText = '' then 99 | Result := True 100 | else 101 | begin 102 | LSubTextLocation := Length(AText) - Length(ASubText); 103 | if LSubTextLocation >= 0 then 104 | Result := SameText(Copy(AText, LSubTextLocation + 1, Length(ASubText)), ASubText) 105 | else 106 | Result := False; 107 | end; 108 | end; 109 | 110 | function InsertString(AIndex: Integer; const AStrings: TArrayOfString; const ANewString: string; const AAllowDuplicates: Boolean): TArrayOfString; 111 | var 112 | I: Integer; 113 | begin 114 | if (not AAllowDuplicates) and ContainsString(AStrings, ANewString, False) then 115 | begin 116 | Result := AStrings; 117 | Exit; 118 | end; 119 | SetArrayLength(Result, GetArrayLength(AStrings) + 1); 120 | for I := 0 to AIndex - 1 do 121 | Result[I] := AStrings[I]; 122 | Result[AIndex] := ANewString; 123 | for I := AIndex to GetArrayLength(AStrings) - 1 do 124 | Result[I + 1] := AStrings[I]; 125 | end; 126 | 127 | function InsertStringAtBeginning(const AStrings: TArrayOfString; const ANewString: string): TArrayOfString; 128 | var 129 | I: Integer; 130 | begin 131 | Result := AStrings; 132 | SetArrayLength(Result, GetArrayLength(Result) + 1); 133 | for I := GetArrayLength(Result) - 1 downto 1 do 134 | Result[I] := Result[I - 1]; 135 | Result[0] := ANewString; 136 | end; 137 | 138 | function JoinStrings(const AStrings: TArrayOfString; const ADelimiter: string; const AJoinEmptyStrings: Boolean): string; 139 | var 140 | LString: string; 141 | I: Integer; 142 | begin 143 | Result := ''; 144 | for I := 0 to GetArrayLength(AStrings) - 1 do 145 | begin 146 | LString := AStrings[I]; 147 | if (Length(LString) > 0) or AJoinEmptyStrings then 148 | begin 149 | if Length(Result) = 0 then 150 | Result := LString 151 | else 152 | Result := Result + ADelimiter + LString; 153 | end; 154 | end; 155 | end; 156 | 157 | function RemoveString(const AStrings: TArrayOfString; const AValue: string; const ACaseSensitive: Boolean): TArrayOfString; 158 | var 159 | LString: string; 160 | I: Integer; 161 | begin 162 | Result := []; 163 | if ACaseSensitive then 164 | begin 165 | for I := 0 to GetArrayLength(AStrings) - 1 do 166 | begin 167 | LString := AStrings[I]; 168 | if LString <> AValue then 169 | Result := AppendString(Result, LString, True); 170 | end; 171 | end 172 | else 173 | for I := 0 to GetArrayLength(AStrings) - 1 do 174 | begin 175 | LString := AStrings[I]; 176 | if not SameText(LString, AValue) then 177 | Result := AppendString(Result, LString, True); 178 | end; 179 | end; 180 | 181 | function ReplaceString(const AStrings: TArrayOfString; const AOldValue, ANewValue: string; const ACaseSensitive, AWholeLine: Boolean): TArrayOfString; 182 | var 183 | LIndex: Integer; 184 | LString: string; 185 | I: Integer; 186 | begin 187 | Result := []; 188 | if ACaseSensitive then 189 | begin 190 | if AWholeLine then 191 | begin 192 | for I := 0 to GetArrayLength(AStrings) - 1 do 193 | begin 194 | LString := AStrings[I]; 195 | if LString = AOldValue then 196 | Result := AppendString(Result, ANewValue, True) 197 | else 198 | Result := AppendString(Result, LString, True); 199 | end; 200 | end 201 | else 202 | begin 203 | for I := 0 to GetArrayLength(AStrings) - 1 do 204 | begin 205 | LString := AStrings[I]; 206 | LIndex := Pos(AOldValue, LString); 207 | if LIndex > 0 then 208 | Result := AppendString(Result, Copy(LString, 1, LIndex - 1) + ANewValue + Copy(LString, LIndex + Length(AOldValue), Length(LString)), True) 209 | else 210 | Result := AppendString(Result, LString, True); 211 | end; 212 | end; 213 | end 214 | else 215 | if AWholeLine then 216 | begin 217 | for I := 0 to GetArrayLength(AStrings) - 1 do 218 | begin 219 | LString := AStrings[I]; 220 | if SameText(LString, AOldValue) then 221 | Result := AppendString(Result, ANewValue, True) 222 | else 223 | Result := AppendString(Result, LString, True); 224 | end; 225 | end 226 | else 227 | begin 228 | for I := 0 to GetArrayLength(AStrings) - 1 do 229 | begin 230 | LString := AStrings[I]; 231 | LIndex := Pos(AnsiLowercase(AOldValue), AnsiLowercase(LString)); 232 | if LIndex > 0 then 233 | Result := AppendString(Result, Copy(LString, 1, LIndex - 1) + ANewValue + Copy(LString, LIndex + Length(AOldValue), Length(LString)), True) 234 | else 235 | Result := AppendString(Result, LString, True); 236 | end; 237 | end; 238 | end; 239 | 240 | function SplitString(AText: string; const ADelimiter: string): TArrayOfString; 241 | var 242 | LTemp: string; 243 | I, P: Integer; 244 | begin 245 | if AText = '' then 246 | begin 247 | Result := []; 248 | Exit; 249 | end; 250 | LTemp := AText; 251 | SetArrayLength(Result, StringChangeEx(LTemp, ADelimiter, '', True) + 1); 252 | for I := 0 to GetArrayLength(Result) - 1 do 253 | begin 254 | P := Pos(ADelimiter, AText); 255 | if P > 0 then 256 | begin 257 | Result[I] := Copy(AText, 1, P - 1); 258 | Delete(AText, 1, P + Length(ADelimiter) - 1); 259 | end 260 | else 261 | Result[I] := AText; 262 | end; 263 | end; 264 | 265 | function StartsWithText(const AText, ASubText: string): Boolean; 266 | begin 267 | if ASubText = '' then 268 | Result := True 269 | else if Length(AText) >= Length(ASubText) then 270 | Result := SameText(Copy(AText, 0, Length(ASubText)), ASubText) 271 | else 272 | Result := False; 273 | end; 274 | 275 | function StrToBoolDef(const AValue: string; const ADefault: Boolean): Boolean; 276 | begin 277 | if SameText(AValue, 'True') or SameText(AValue, 'Yes') or (AValue = '1') then 278 | Result := True 279 | else if SameText(AValue, 'False') or SameText(AValue, 'No') or (AValue = '0') then 280 | Result := False 281 | else 282 | Result := ADefault; 283 | end; 284 | 285 | // end. 286 | #endif 287 | -------------------------------------------------------------------------------- /Style/Amakrits.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Amakrits.vsf -------------------------------------------------------------------------------- /Style/AmethystKamri.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/AmethystKamri.vsf -------------------------------------------------------------------------------- /Style/AquaGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/AquaGraphite.vsf -------------------------------------------------------------------------------- /Style/AquaLightSlate.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/AquaLightSlate.vsf -------------------------------------------------------------------------------- /Style/Auric.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Auric.vsf -------------------------------------------------------------------------------- /Style/BlueGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/BlueGraphite.vsf -------------------------------------------------------------------------------- /Style/Carbon.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Carbon.vsf -------------------------------------------------------------------------------- /Style/CharcoalDarkSlate.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/CharcoalDarkSlate.vsf -------------------------------------------------------------------------------- /Style/CobaltXEMedia.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/CobaltXEMedia.vsf -------------------------------------------------------------------------------- /Style/CyanDusk.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/CyanDusk.vsf -------------------------------------------------------------------------------- /Style/CyanNight.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/CyanNight.vsf -------------------------------------------------------------------------------- /Style/EmeraldLightSlate.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/EmeraldLightSlate.vsf -------------------------------------------------------------------------------- /Style/Glossy.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Glossy.vsf -------------------------------------------------------------------------------- /Style/Glow.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Glow.vsf -------------------------------------------------------------------------------- /Style/GoldenGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/GoldenGraphite.vsf -------------------------------------------------------------------------------- /Style/GreenGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/GreenGraphite.vsf -------------------------------------------------------------------------------- /Style/IcebergClassico.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/IcebergClassico.vsf -------------------------------------------------------------------------------- /Style/LavenderClassico.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/LavenderClassico.vsf -------------------------------------------------------------------------------- /Style/Light.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Light.vsf -------------------------------------------------------------------------------- /Style/LightGreen.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/LightGreen.vsf -------------------------------------------------------------------------------- /Style/Luna.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Luna.vsf -------------------------------------------------------------------------------- /Style/OnyxBlue.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/OnyxBlue.vsf -------------------------------------------------------------------------------- /Style/OrangeGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/OrangeGraphite.vsf -------------------------------------------------------------------------------- /Style/Pink.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Pink.vsf -------------------------------------------------------------------------------- /Style/RubyGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/RubyGraphite.vsf -------------------------------------------------------------------------------- /Style/SapphireKamri.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/SapphireKamri.vsf -------------------------------------------------------------------------------- /Style/Sky.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Sky.vsf -------------------------------------------------------------------------------- /Style/SlateClassico.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/SlateClassico.vsf -------------------------------------------------------------------------------- /Style/SmokeyQuartzKamri.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/SmokeyQuartzKamri.vsf -------------------------------------------------------------------------------- /Style/TabletDark.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/TabletDark.vsf -------------------------------------------------------------------------------- /Style/TurquoiseGray.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/TurquoiseGray.vsf -------------------------------------------------------------------------------- /Style/Windows10.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Windows10.vsf -------------------------------------------------------------------------------- /Style/Windows10Blue.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Windows10Blue.vsf -------------------------------------------------------------------------------- /Style/Windows10Dark.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Windows10Dark.vsf -------------------------------------------------------------------------------- /Style/Windows11.Dark.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/Windows11.Dark.vsf -------------------------------------------------------------------------------- /Style/YellowGraphite.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/YellowGraphite.vsf -------------------------------------------------------------------------------- /Style/khaki.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/khaki.vsf -------------------------------------------------------------------------------- /Style/lilac.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/lilac.vsf -------------------------------------------------------------------------------- /Style/sepia.vsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Style/sepia.vsf -------------------------------------------------------------------------------- /Style/vcl-styles-plugins/README.md: -------------------------------------------------------------------------------- 1 | The VCL Styles Plugins is a collection of plugins for skining third party installers and apps using the VCL Styles. 2 | 3 | ![logo](https://github.com/RRUZ/vcl-styles-plugins/blob/master/images/nsis_inno.png) 4 | 5 | ### VCL Styles for Inno Setup 6 | 7 | ![](https://github.com/RRUZ/vcl-styles-plugins/blob/master/InnoSetup%20plugin/Images%20Site/output_6Rb98T.gif) 8 | 9 | 10 | This plugin (dll) allow skin the installers created by Inno Setup. for more info check this [page](https://github.com/RRUZ/vcl-styles-plugins/wiki/Inno-Setup). 11 | 12 | ### VCL Styles for NSIS 13 | 14 | ![](https://github.com/RRUZ/vcl-styles-plugins/blob/master/NSIS%20plugin/Images/output_Jd3n7s.gif) 15 | 16 | 17 | This plugin (dll) allow skin the installers created by NSIS. for more info check this [page](https://github.com/RRUZ/vcl-styles-plugins/wiki/NSIS). 18 | -------------------------------------------------------------------------------- /Template/Setup.iss: -------------------------------------------------------------------------------- 1 | [Code] 2 | {************************************************************************} 3 | { } 4 | { Ethea InnoSetup Tools Library } 5 | { } 6 | { Copyright (c) 2024-2025 Ethea S.r.l. } 7 | { } 8 | { Original Code is Copyright (c) 2021-2024 Skia4Delphi Project. } 9 | { } 10 | { Use of this source code is governed by the MIT license that can be } 11 | { found in the LICENSE file. } 12 | { } 13 | {************************************************************************} 14 | { } 15 | { Custom Parameters } 16 | { } 17 | { /RADStudioVersions= } 18 | { Values allowed: 10.0 to 24.0 separed by comma or all keyword } 19 | { Default: (latest version found in computer) } 20 | { Description: The version used is the product version in resgistry, } 21 | { i.e, the RAD Studio 11 Alexandria is "22.0", the RAD Studio 12 } 22 | { Athens is "23.0", etc. This is used to set the RAD Studio } 23 | { versions, in silent mode, that will installed the library. } 24 | { Ex: /RADStudioVersions=23.0,22.0 will install only in } 25 | { RAD Studio 12 Athens and 11 Alexandria. But if the parameter is } 26 | { /RADStudioVersions=all will install in all RAD Studio installed in } 27 | { the machine. Without set this parameter, the value will be only } 28 | { the newest RAD Studio version found on the machine. A cool tip of } 29 | { this param is that if the setup is being executed by the GetIt, } 30 | { you can replace the version number to the environment variable } 31 | { ProductVersion like this: /RADStudioVersions=$(ProductVersion) } 32 | { } 33 | { /CreateUninstallRegKey= } 34 | { Values allowed: no|yes or false|true or 0|1 } 35 | { Default: yes } 36 | { Description: When true the uninstall shortcut in applications panel } 37 | { will be created and before the setup starts will call the } 38 | { uninstall of others versions } 39 | { } 40 | {************************************************************************} 41 | { } 42 | { Example of command line to install in silent mode: } 43 | { cmd /C ""SVGIconImageList_4.3.0_Setup.exe" } 44 | { /DIR="C:\Dev\SVGIconImageList" /SILENT } 45 | { /RADStudioVersions=all" } 46 | { } 47 | { In GetIt implementation, the installation command could be: } 48 | { cmd /C ""$(BDSCatalogRepository)\SVGIconImageList-4.3.0\ } 49 | { SVGIconImageList_4.3.0_Setup.exe" } 50 | { /DIR="$(BDSCatalogRepository)\SVGIconImageList-4.3.0" /VERYSILENT } 51 | { /RADStudioVersions=$(ProductVersion) /CreateUninstallRegKey=no" } 52 | { } 53 | { Example of command line to uninstall in silent mode: } 54 | { cmd /C ""C:\SVGIconImageList\unins000.exe" /VERYSILENT } 55 | { /RADStudioVersions=all" } 56 | { } 57 | { In GetIt implementation, the uninstall command could be: } 58 | { cmd /C ""$(BDSCatalogRepository)\SVGIconImageList-4.3.0\unins000.exe"} 59 | { /VERYSILENT /RADStudioVersions=$(ProductVersion)" } 60 | { } 61 | {************************************************************************} 62 | 63 | //TODO: define those values for your Library 64 | #define LibraryName "MyLibraryName" 65 | #define SetupName "MyLibraryFolder" 66 | #define LibraryVersion "1.0.0" 67 | #define LibraryPublisher "My Company" 68 | #define LibraryCopyright "Copyright (c) 2024 MyCompany" 69 | #define LibraryURL "https://mycompany.com/MyLibrary/" 70 | #define LibrarySamplesFolder "Demos" 71 | #define LibraryPackagesFolder "Packages" 72 | #define LibrarySourceFolder "Source" 73 | #define LibraryDCUFolder "Lib" 74 | #define LibraryDocumentationURL "https://mycompany.com/MyLibrary/docs" 75 | #define LibrarySupportURL "https://github.com/mycompany/MyLibrary/issues/" 76 | #define LibraryUpdatesURL "https://github.com/EtheaDev/SVGIconImageList/releases/" 77 | #define LibraryLicenseFileName "..\LICENSE" 78 | #define BannerImagesFileName "WizClassicImage.bmp" 79 | #define SmallImagesFileName "WizClassicSmallImage.bmp" 80 | #define SetupFolder "Setup" 81 | #define FilesEmbedded 82 | //TODO: you can choose your preferred Style contained in folder: InnoSetupScripts\Style 83 | //#define VclStyle "Windows11.Dark.vsf" 84 | 85 | [Setup] 86 | AllowCancelDuringInstall=yes 87 | AppCopyright={#LibraryCopyright} 88 | ; TODO: To generate a new GUID, click Tools | Generate GUID inside the IDE. 89 | ; NOTE: The value of AppId uniquely identifies this application. 90 | ; Do not use the same AppId value in installers for other applications. 91 | AppId={{00000000-0000-0000-0000-000000000000} 92 | AppName={#LibraryName} 93 | AppPublisher={#LibraryPublisher} 94 | AppPublisherURL={#LibraryURL} 95 | AppSupportURL={#LibrarySupportURL} 96 | AppUpdatesURL={#LibraryUpdatesURL} 97 | AppVersion={#LibraryVersion} 98 | CloseApplications=no 99 | Compression=lzma2/ultra64 100 | CreateUninstallRegKey=NeedsUninstallRegKey 101 | DefaultDirName={code:GetDefaultDirName} 102 | DefaultGroupName={#LibraryName} 103 | DirExistsWarning=no 104 | DisableDirPage=no 105 | DisableProgramGroupPage=yes 106 | DisableReadyPage=yes 107 | DisableStartupPrompt=yes 108 | DisableWelcomePage=no 109 | InternalCompressLevel=ultra64 110 | LicenseFile={#LibraryLicenseFileName} 111 | LZMANumBlockThreads=6 112 | LZMAUseSeparateProcess=yes 113 | MissingMessagesWarning=yes 114 | NotRecognizedMessagesWarning=yes 115 | PrivilegesRequired=lowest 116 | SetupLogging=yes 117 | ShowLanguageDialog=no 118 | SolidCompression=yes 119 | UsePreviousAppDir=no 120 | WizardImageFile={#BannerImagesFileName} 121 | WizardSmallImageFile={#SmallImagesFileName} 122 | OutputBaseFilename={#SetupName}_{#LibraryVersion}_Setup 123 | OutputDir=.\Output\ 124 | Uninstallable=yes 125 | 126 | [Languages] 127 | Name: "english"; MessagesFile: "compiler:Default.isl,.\InnoSetupScripts\Languages\Default.isl" 128 | Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl,.\InnoSetupScripts\Languages\BrazilianPortuguese.isl" 129 | Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl,.\InnoSetupScripts\Languages\Catalan.isl" 130 | Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl,.\InnoSetupScripts\Languages\Default.isl" 131 | Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl,.\InnoSetupScripts\Languages\Default.isl" 132 | Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl,.\InnoSetupScripts\Languages\Default.isl" 133 | Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl,.\InnoSetupScripts\Languages\Default.isl" 134 | Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl,.\InnoSetupScripts\Languages\Default.isl" 135 | Name: "french"; MessagesFile: "compiler:Languages\French.isl,.\InnoSetupScripts\Languages\French.isl" 136 | Name: "german"; MessagesFile: "compiler:Languages\German.isl,.\InnoSetupScripts\Languages\German.isl" 137 | Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl,.\InnoSetupScripts\Languages\Default.isl" 138 | Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl,.\InnoSetupScripts\Languages\Italian.isl" 139 | Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl,.\InnoSetupScripts\Languages\Default.isl" 140 | Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl,.\InnoSetupScripts\Languages\Default.isl" 141 | Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl,.\InnoSetupScripts\Languages\Default.isl" 142 | Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl,.\InnoSetupScripts\Languages\Default.isl" 143 | Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl,.\InnoSetupScripts\Languages\Default.isl" 144 | Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl,.\InnoSetupScripts\Languages\Default.isl" 145 | Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl,.\InnoSetupScripts\Languages\Spanish.isl" 146 | Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl,.\InnoSetupScripts\Languages\Default.isl" 147 | Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl,.\InnoSetupScripts\Languages\Default.isl" 148 | 149 | #expr Exec(SourcePath + '\.\InnoSetupScripts\Scripts\Setup.Preprocessor.ClearFiles.bat', '', SourcePath + '\.\InnoSetupScripts\Scripts\') 150 | #define CommonRADStudioFilesExcludes "*.exe,*.dll,*.bpl,*.bpi,*.dcp,*.so,*.apk,*.drc,*.map,*.dres,*.rsm,*.tds,*.dcu,*.lib,*.jdbg,*.plist,*.cfg,*Resource.rc,*.cfg,*Resource.rc,*.local,*.identcache,*.projdata,*.tvsconfig,*.skincfg,*.cbk,*.dsk,__history\*,__recovery\*,*.~*,*.stat,modules\*,.github\*,*template*\*,*template*,*.a,*.dex,*.o,*.vrc,*.res,*.log,*.deployproj,*.bak,unins0*.dat,*.nupkg" 151 | ; Don't change the order of the files. This could affect the performance when extract temp files 152 | [Files] 153 | #ifdef VclStyle 154 | Source: ".\InnoSetupScripts\Style\*"; DestDir: "{app}\{#SetupFolder}\Style"; Flags: ignoreversion 155 | #endif 156 | Source: "..\{#LibraryPackagesFolder}\*"; Excludes: "{#CommonRADStudioFilesExcludes}"; DestDir: "{app}\{#LibraryPackagesFolder}"; Flags: recursesubdirs ignoreversion 157 | Source: "..\*"; Excludes: "{#CommonRADStudioFilesExcludes},*.gitattributes,*.gitignore,*.gitmodules,\.github\*,\.history\*,\Documents\*,\Externals\*,\{#LibraryDCUFolder}\*,Logs\*,*.Logs.txt,Objects\*,\{#SetupFolder}\*,\{#LibraryPackagesFolder}\*,\Test"; DestDir: "{app}"; Flags: recursesubdirs ignoreversion 158 | // TODO: Add here extra files to install, for example Custom Resources (.res) files used by your Library 159 | ; Source: "..\{#LibraryPackagesFolder}\CustomResources.res"; DestDir: "{app}\{#LibraryPackagesFolder}"; Flags: ignoreversion 160 | 161 | [Icons] 162 | Name: "{group}\Uninstall"; Filename: "{uninstallexe}" 163 | 164 | [Run] 165 | Filename: "{app}\{#LibrarySamplesFolder}"; Description: "{cm:SetupOpenSamplesFolder}"; Flags: shellexec runasoriginaluser postinstall; 166 | Filename: "{#LibraryDocumentationURL}"; Description: "{cm:SetupViewOnlineDocumentation}"; Flags: shellexec runasoriginaluser postinstall unchecked; 167 | 168 | [UninstallDelete] 169 | //TODO: Add the Folder list of your project 170 | Type: filesandordirs; Name: "{app}\Demos\*"; 171 | Type: filesandordirs; Name: "{app}\Lib\*"; 172 | Type: filesandordirs; Name: "{app}\Packages\*"; 173 | Type: filesandordirs; Name: "{app}\Source\*"; 174 | Type: filesandordirs; Name: "{app}\LICENSE"; 175 | Type: filesandordirs; Name: "{app}\README.htm"; 176 | Type: filesandordirs; Name: "{app}\README.md"; 177 | Type: dirifempty; Name: "{app}\Demos"; 178 | Type: dirifempty; Name: "{app}\Lib"; 179 | Type: dirifempty; Name: "{app}\Packages"; 180 | Type: dirifempty; Name: "{app}\Source"; 181 | Type: dirifempty; Name: "{app}"; 182 | 183 | // Include 184 | #include ".\InnoSetupScripts\Source\Setup.Main.inc" 185 | 186 | [code] 187 | const 188 | //TODO: Change LibraryDirVariable for the Environment variabile of your library 189 | LibraryDirVariable = 'LIBDIR'; 190 | LibraryDirDefine = '$(' + LibraryDirVariable + ')'; 191 | 192 | /// Make custom changes before the installation 193 | function _OnTryPrepareProjectInstallation(var AProjectItem: TRADStudioGroupProjectItem; const AInfo: TRADStudioInfo): Boolean; forward; 194 | /// Make custom changes before the uninstallation 195 | function _OnTryPrepareProjectUninstallation(var AProjectItem: TRADStudioGroupProjectItem; const AInfo: TRADStudioInfo): Boolean; forward; 196 | 197 | var 198 | _FRADStudioInstalledList: TArrayOfString; 199 | _FRADStudioUninstalledList: TArrayOfString; 200 | 201 | function _OnTryPrepareProjectInstallation(var AProjectItem: TRADStudioGroupProjectItem; const AInfo: TRADStudioInfo): Boolean; 202 | var 203 | I: Integer; 204 | LAppPath: string; 205 | LPlatform: TProjectPlatform; 206 | begin 207 | Log(Format('_OnTryPrepareProjectInstallation: Preparing package "%s" before install...', [AProjectItem.Project.FileName])); 208 | if not ContainsString(_FRADStudioInstalledList, AInfo.Version.RegVersion, False) then 209 | begin 210 | _FRADStudioInstalledList := AppendString(_FRADStudioInstalledList, AInfo.Version.RegVersion, False); 211 | end; 212 | LAppPath := ExpandConstant('{app}'); 213 | for I := 0 to GetArrayLength(AProjectItem.Project.SourcePaths) - 1 do 214 | StringChangeEx(AProjectItem.Project.SourcePaths[I], LAppPath, LibraryDirDefine, True); 215 | StringChangeEx(AProjectItem.Project.DCUOutputPath, LAppPath, LibraryDirDefine, True); 216 | Result := TryAddRADStudioEnvVariable(AInfo.Version, LibraryDirVariable, ExpandConstant('{app}')); 217 | end; 218 | 219 | function _OnTryPrepareProjectUninstallation(var AProjectItem: TRADStudioGroupProjectItem; const AInfo: TRADStudioInfo): Boolean; 220 | var 221 | I: Integer; 222 | LAppPath: string; 223 | LPlatform: TProjectPlatform; 224 | begin 225 | Log(Format('_OnTryPrepareProjectUninstallation: Preparing package "%s" to uninstall...', [AProjectItem.Project.FileName])); 226 | if not ContainsString(_FRADStudioUninstalledList, AInfo.Version.RegVersion, False) then 227 | begin 228 | _FRADStudioUninstalledList := AppendString(_FRADStudioUninstalledList, AInfo.Version.RegVersion, False); 229 | end; 230 | LAppPath := ExpandConstant('{app}'); 231 | for I := 0 to GetArrayLength(AProjectItem.Project.SourcePaths) - 1 do 232 | StringChangeEx(AProjectItem.Project.SourcePaths[I], LAppPath, LibraryDirDefine, True); 233 | StringChangeEx(AProjectItem.Project.DCUOutputPath, LAppPath, LibraryDirDefine, True); 234 | Result := TryRemoveRADStudioEnvVariable(AInfo.Version, LibraryDirVariable); 235 | if not Result then 236 | Log(Format('_OnTryPrepareProjectUninstallation: Failed to prepare the project "%s"', [AProjectItem.Project.FileName])); 237 | end; 238 | 239 | 240 | function _InitializeSetup: Boolean; 241 | begin 242 | FOnTryPrepareProjectInstallation := @_OnTryPrepareProjectInstallation; 243 | FOnTryPrepareProjectUninstallation := @_OnTryPrepareProjectUninstallation; 244 | Result := True; 245 | end; 246 | 247 | 248 | function _InitializeUninstall: Boolean; 249 | begin 250 | FOnTryPrepareProjectUninstallation := @_OnTryPrepareProjectUninstallation; 251 | Result := True; 252 | end; 253 | -------------------------------------------------------------------------------- /Template/WizClassicImage.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Template/WizClassicImage.bmp -------------------------------------------------------------------------------- /Template/WizClassicSmallImage.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EtheaDev/InnoSetupScripts/6aa0d425bff6b2e21cbbf966ebdd54d1670b1f97/Template/WizClassicSmallImage.bmp --------------------------------------------------------------------------------