├── .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 | [](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 | 
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 | 
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 | 
4 |
5 | ### VCL Styles for Inno Setup
6 |
7 | 
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 | 
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
--------------------------------------------------------------------------------