{**************************************************************************************************} { } { Project JEDI Code Library (JCL) } { } { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); } { you may not use this file except in compliance with the License. You may obtain a copy of the } { License at http://www.mozilla.org/MPL/ } { } { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } { ANY KIND, either express or implied. See the License for the specific language governing rights } { and limitations under the License. } { } { The Original Code is DelphiInstall.pas. } { } { The Initial Developer of the Original Code is Petr Vones. Portions created by Petr Vones are } { Copyright (C) of Petr Vones. All Rights Reserved. } { } { Contributor(s): } { Andreas Hausladen (ahuser) } { Florent Ouchet (outchy) } { Robert Marquardt (marquardt) } { Robert Rossmair (rrossmair) - crossplatform & BCB support } { Uwe Schuster (uschuster) } { } {**************************************************************************************************} { } { Routines for getting information about installed versions of Delphi/C++Builder and performing } { basic installation tasks. } { } { Important notes for C#Builder 1 and Delphi 8: } { These products were not shipped with their native compilers, but the toolkit to build design } { packages is available in codecentral (http://codecentral.borland.com): } { - "IDE Integration pack for C#Builder 1.0" http://codecentral.borland.com/Item.aspx?ID=21334 } { - "IDE Integration pack for Delphi 8" http://codecentral.borland.com/Item.aspx?ID=21333 } { It's recommended to extract zip files using the standard pattern of Delphi directories: } { - Binary files go to \bin (DCC32.EXE, RLINK32.DLL and lnkdfm7*.dll) } { - Compiler files go to \lib (designide.dcp, rtl.dcp, SysInit.dcu, vcl.dcp, vclactnband.dcp, } { vcljpg.dcp and vclx.dcp) } { - ToolsAPI files go to \source\ToolsAPI (PaletteAPI.pas, PropInspAPI.pas and ToolsAPI.pas) } { Don't mix C#Builder 1 files with Delphi 8 and vice-versa otherwise the compilation will fail } { !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } { !!!!!!!! The DCPPath for these releases have to $(BDS)\lib !!!!!!!!! } { !!!!!!!! or the directory where compiler files were extracted !!!!!!!!! } { !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } { The default BPL output directory for these products is set to $(BDSPROJECTSDIR)\bpl, it may not } { exist since the product installers don't create it } { } {**************************************************************************************************} { } { Unit owner: Petr Vones } { } {**************************************************************************************************} // Last modified: $Date: 2007-06-16 20:31:47 +0200 (sam., 16 juin 2007) $ unit JclBorlandTools; {$I jcl.inc} {$I crossplatform.inc} interface uses {$IFDEF UNITVERSIONING} JclUnitVersioning, {$ENDIF UNITVERSIONING} {$IFDEF MSWINDOWS} Windows, MSHelpServices_TLB, {$ENDIF MSWINDOWS} Classes, SysUtils, IniFiles, Contnrs, JclBase, JclSysUtils; // Various definitions type EJclBorRADException = class(EJclError); TJclBorRADToolKind = (brDelphi, brCppBuilder, brBorlandDevStudio); {$IFDEF KYLIX} TJclBorRADToolEdition = (deOPEN, dePRO, deSVR); {$ELSE} TJclBorRADToolEdition = (deSTD, dePRO, deCSS, deARC); {$ENDIF KYLIX} TJclBorRADToolPath = string; const SupportedDelphiVersions = [5, 6, 7, 8, 9, 10, 11]; SupportedBCBVersions = [5, 6, 10, 11]; SupportedBDSVersions = [1, 2, 3, 4, 5]; // Object Repository BorRADToolRepositoryPagesSection = 'Repository Pages'; BorRADToolRepositoryDialogsPage = 'Dialogs'; BorRADToolRepositoryFormsPage = 'Forms'; BorRADToolRepositoryProjectsPage = 'Projects'; BorRADToolRepositoryDataModulesPage = 'Data Modules'; BorRADToolRepositoryObjectType = 'Type'; BorRADToolRepositoryFormTemplate = 'FormTemplate'; BorRADToolRepositoryProjectTemplate = 'ProjectTemplate'; BorRADToolRepositoryObjectName = 'Name'; BorRADToolRepositoryObjectPage = 'Page'; BorRADToolRepositoryObjectIcon = 'Icon'; BorRADToolRepositoryObjectDescr = 'Description'; BorRADToolRepositoryObjectAuthor = 'Author'; BorRADToolRepositoryObjectAncestor = 'Ancestor'; BorRADToolRepositoryObjectDesigner = 'Designer'; // Delphi 6+ only BorRADToolRepositoryDesignerDfm = 'dfm'; BorRADToolRepositoryDesignerXfm = 'xfm'; BorRADToolRepositoryObjectNewForm = 'DefaultNewForm'; BorRADToolRepositoryObjectMainForm = 'DefaultMainForm'; SourceExtensionDelphiPackage = '.dpk'; SourceExtensionBCBPackage = '.bpk'; SourceExtensionDelphiProject = '.dpr'; SourceExtensionBCBProject = '.bpr'; SourceExtensionBDSProject = '.bdsproj'; SourceExtensionDProject = '.dproj'; BinaryExtensionPackage = '.bpl'; BinaryExtensionLibrary = '.dll'; BinaryExtensionExecutable = '.exe'; CompilerExtensionDCP = '.dcp'; CompilerExtensionBPI = '.bpi'; CompilerExtensionLIB = '.lib'; CompilerExtensionTDS = '.tds'; CompilerExtensionMAP = '.map'; CompilerExtensionDRC = '.drc'; CompilerExtensionDEF = '.def'; SourceExtensionCPP = '.cpp'; SourceExtensionH = '.h'; SourceExtensionPAS = '.pas'; SourceExtensionDFM = '.dfm'; SourceExtensionXFM = '.xfm'; SourceDescriptionPAS = 'Pascal source file'; SourceDescriptionCPP = 'C++ source file'; DesignerVCL = 'VCL'; DesignerCLX = 'CLX'; ProjectTypePackage = 'package'; ProjectTypeLibrary = 'library'; ProjectTypeProgram = 'program'; Personality32Bit = '32 bit'; Personality64Bit = '64 bit'; PersonalityDelphi = 'Delphi'; PersonalityDelphiDotNet = 'Delphi.net'; PersonalityBCB = 'C++Builder'; PersonalityCSB = 'C#Builder'; PersonalityVB = 'Visual Basic'; PersonalityDesign = 'Design'; PersonalityUnknown = 'Unknown personality'; PersonalityBDS = 'Borland Developer Studio'; DOFDirectoriesSection = 'Directories'; DOFUnitOutputDirKey = 'UnitOutputDir'; DOFSearchPathName = 'SearchPath'; DOFConditionals = 'Conditionals'; DOFLinkerSection = 'Linker'; DOFPackagesKey = 'Packages'; DOFCompilerSection = 'Compiler'; DOFPackageNoLinkKey = 'PackageNoLink'; {$IFDEF KYLIX} BorRADToolEditionIDs: array [TJclBorRADToolEdition] of PChar = ('OPEN', 'PRO', 'SVR'); {$ELSE ~KYLIX} BorRADToolEditionIDs: array [TJclBorRADToolEdition] of PChar = ('STD', 'PRO', 'CSS', 'ARC'); // 'ARC' is an assumption {$ENDIF ~KYLIX} // Installed versions information classes type TJclBorPersonality = (bpDelphi32, bpDelphi64, bpBCBuilder32, bpBCBuilder64, bpDelphiNet32, bpDelphiNet64, bpCSBuilder32, bpCSBuilder64, bpVisualBasic32, bpVisualBasic64, bpDesign, bpUnknown); // bpDelphi64, bpBCBuilder64); TJclBorPersonalities = set of TJclBorPersonality; TJclBorDesigner = (bdVCL, bdCLX); TJclBorDesigners = set of TJClBorDesigner; TJclBorPlatform = (bp32bit, bp64bit); const JclBorPersonalityDescription: array [TJclBorPersonality] of string = ( Personality32Bit + ' ' + PersonalityDelphi, Personality64Bit + ' ' + PersonalityDelphi, Personality32Bit + ' ' + PersonalityBCB, Personality64Bit + ' ' + PersonalityBCB, Personality32Bit + ' ' + PersonalityDelphiDotNet, Personality64Bit + ' ' + PersonalityDelphiDotNet, Personality32Bit + ' ' + PersonalityCSB, Personality64Bit + ' ' + PersonalityCSB, Personality32Bit + ' ' + PersonalityVB, Personality64Bit + ' ' + PersonalityVB, PersonalityDesign, PersonalityUnknown ); JclBorDesignerDescription: array [TJclBorDesigner] of string = (DesignerVCL, DesignerCLX); JclBorDesignerFormExtension: array [TJclBorDesigner] of string = (SourceExtensionDFM, SourceExtensionXFM); type TJclBorRADToolInstallation = class; TJclBorRADToolInstallationObject = class(TInterfacedObject) private FInstallation: TJclBorRADToolInstallation; protected constructor Create(AInstallation: TJclBorRADToolInstallation); public property Installation: TJclBorRADToolInstallation read FInstallation; end; {$IFDEF MSWINDOWS} TJclBorlandOpenHelp = class(TJclBorRADToolInstallationObject) private function GetContentFileName: string; function GetIndexFileName: string; function GetLinkFileName: string; function GetGidFileName: string; function GetProjectFileName: string; function ReadFileName(const FormatName: string): string; public function AddHelpFile(const HelpFileName, IndexName: string): Boolean; function RemoveHelpFile(const HelpFileName, IndexName: string): Boolean; property ContentFileName: string read GetContentFileName; property GidFileName: string read GetGidFileName; property IndexFileName: string read GetIndexFileName; property LinkFileName: string read GetLinkFileName; property ProjectFileName: string read GetProjectFileName; end; TJclHelp2Object = (hoRegisterSession, hoRegister, hoPlugin); TJclHelp2Objects = set of TJclHelp2Object; TJclHelp2Manager = class(TJclBorRADToolInstallationObject) private FHxRegisterSession: IHxRegisterSession; FHxRegister: IHxRegister; FHxPlugin: IHxPlugIn; FIdeNameSpace: WideString; function RequireObject(HelpObjects: TJclHelp2Objects): Boolean; function GetHxPlugin: IHxPlugin; function GetHxRegister: IHxRegister; function GetHxRegisterSession: IHxRegisterSession; protected constructor Create(AInstallation: TJclBorRADToolInstallation); overload; public constructor Create; overload; destructor Destroy; override; function CreateTransaction: Boolean; function CommitTransaction: Boolean; function RegisterNameSpace(const Name, Collection, Description: WideString): Boolean; function UnregisterNameSpace(const Name: WideString): Boolean; function RegisterHelpFile(const NameSpace, Identifier: WideString; const LangId: Integer; const HxSFile, HxIFile: WideString): Boolean; function UnregisterHelpFile(const NameSpace, Identifier: WideString; const LangId: Integer): Boolean; function PlugNameSpaceIn(const SourceNameSpace, TargetNameSpace: WideString): Boolean; function UnPlugNameSpace(const SourceNameSpace, TargetNameSpace: WideString): Boolean; function PlugNameSpaceInBorlandHelp(const NameSpace: WideString): Boolean; function UnPlugNameSpaceFromBorlandHelp(const NameSpace: WideString): Boolean; property HxRegisterSession: IHxRegisterSession read GetHxRegisterSession; property HxRegister: IHxRegister read GetHxRegister; property HxPlugin: IHxPlugin read GetHxPlugin; property IdeNamespace: WideString read FIdeNameSpace; end; {$ENDIF MSWINDOWS} TJclBorRADToolIdeTool = class(TJclBorRADToolInstallationObject) private FKey: string; function GetCount: Integer; function GetParameters(Index: Integer): string; function GetPath(Index: Integer): string; function GetTitle(Index: Integer): string; function GetWorkingDir(Index: Integer): string; procedure SetCount(const Value: Integer); procedure SetParameters(Index: Integer; const Value: string); procedure SetPath(Index: Integer; const Value: string); procedure SetTitle(Index: Integer; const Value: string); procedure SetWorkingDir(Index: Integer; const Value: string); protected constructor Create(AInstallation: TJclBorRADToolInstallation); procedure CheckIndex(Index: Integer); public property Count: Integer read GetCount write SetCount; function IndexOfPath(const Value: string): Integer; function IndexOfTitle(const Value: string): Integer; procedure RemoveIndex(const Index: Integer); property Key: string read FKey; property Title[Index: Integer]: string read GetTitle write SetTitle; property Path[Index: Integer]: string read GetPath write SetPath; property Parameters[Index: Integer]: string read GetParameters write SetParameters; property WorkingDir[Index: Integer]: string read GetWorkingDir write SetWorkingDir; end; TJclBorRADToolIdePackages = class(TJclBorRADToolInstallationObject) private FDisabledPackages: TStringList; FKnownPackages: TStringList; FKnownIDEPackages: TStringList; FExperts: TStringList; function GetCount: Integer; function GetIDECount: Integer; function GetExpertCount: Integer; function GetPackageDescriptions(Index: Integer): string; function GetIDEPackageDescriptions(Index: Integer): string; function GetExpertDescriptions(Index: Integer): string; function GetPackageDisabled(Index: Integer): Boolean; function GetPackageFileNames(Index: Integer): string; function GetIDEPackageFileNames(Index: Integer): string; function GetExpertFileNames(Index: Integer): string; protected constructor Create(AInstallation: TJclBorRADToolInstallation); function PackageEntryToFileName(const Entry: string): string; procedure ReadPackages; procedure RemoveDisabled(const FileName: string); public destructor Destroy; override; function AddPackage(const FileName, Description: string): Boolean; function AddIDEPackage(const FileName, Description: string): Boolean; function AddExpert(const FileName, Description: string): Boolean; function RemovePackage(const FileName: string): Boolean; function RemoveIDEPackage(const FileName: string): Boolean; function RemoveExpert(const FileName: string): Boolean; property Count: Integer read GetCount; property IDECount: Integer read GetIDECount; property ExpertCount: Integer read GetExpertCount; property PackageDescriptions[Index: Integer]: string read GetPackageDescriptions; property IDEPackageDescriptions[Index: Integer]: string read GetIDEPackageDescriptions; property ExpertDescriptions[Index: Integer]: string read GetExpertDescriptions; property PackageFileNames[Index: Integer]: string read GetPackageFileNames; property IDEPackageFileNames[Index: Integer]: string read GetIDEPackageFileNames; property ExpertFileNames[Index: Integer]: string read GetExpertFileNames; property PackageDisabled[Index: Integer]: Boolean read GetPackageDisabled; end; {$HPPEMIT 'namespace Jclborlandtools'} {$HPPEMIT '{'} {$HPPEMIT ' // For some reason, the generator puts this interface after its first'} {$HPPEMIT ' // usage, resulting in an unusable header file. We fix this by forward'} {$HPPEMIT ' // declaring the interface.'} {$HPPEMIT ' __interface IJclCommandLineTool;'} (*$HPPEMIT '}'*) IJclCommandLineTool = interface ['{A0034B09-A074-D811-847D-0030849E4592}'] function GetExeName: string; function GetOptions: TStrings; function GetOutput: string; function GetOutputCallback: TTextHandler; procedure AddPathOption(const Option, Path: string); function Execute(const CommandLine: string): Boolean; procedure SetOutputCallback(const CallbackMethod: TTextHandler); property ExeName: string read GetExeName; property Options: TStrings read GetOptions; property OutputCallback: TTextHandler write SetOutputCallback; property Output: string read GetOutput; end; EJclCommandLineToolError = class(EJclError); TJclCommandLineTool = class(TInterfacedObject, IJclCommandLineTool) private FExeName: string; FOptions: TStringList; FOutput: string; FOutputCallback: TTextHandler; protected function GetExeName: string; function GetOutput: string; function GetOptions: TStrings; function GetOutputCallback: TTextHandler; procedure SetOutputCallback(const CallbackMethod: TTextHandler); constructor Create(const AExeName: string); procedure AddPathOption(const Option, Path: string); function Execute(const CommandLine: string): Boolean; property ExeName: string read GetExeName; property Output: string read GetOutput; public destructor Destroy; override; end; TJclBorlandCommandLineTool = class(TJclBorRADToolInstallationObject, IJclCommandLineTool) private FOptions: TStringList; FOutputCallback: TTextHandler; FOutput: string; protected constructor Create(AInstallation: TJclBorRADToolInstallation); virtual; procedure CheckOutputValid; function GetExeName: string; virtual; function GetFileName: string; function GetOptions: TStrings; function GetOutputCallback: TTextHandler; procedure SetOutputCallback(const CallbackMethod: TTextHandler); function GetOutput: string; public destructor Destroy; override; procedure AddPathOption(const Option, Path: string); function Execute(const CommandLine: string): Boolean; virtual; property FileName: string read GetFileName; property Output: string read GetOutput; property OutputCallback: TTextHandler read FOutputCallback write SetOutputCallback; property Options: TStrings read GetOptions; end; TJclBCC32 = class(TJclBorlandCommandLineTool) protected constructor Create(AInstallation: TJclBorRADToolInstallation); override; function GetExeName: string; override; public {$IFDEF KEEP_DEPRECATED} function SupportsLibSuffix: Boolean; {$ENDIF KEEP_DEPRECATED} end; TJclDCC32 = class(TJclBorlandCommandLineTool) private FOnBeforeSaveOptionsToFile: TNotifyEvent; protected constructor Create(AInstallation: TJclBorRADToolInstallation); override; function GetExeName: string; override; procedure SaveOptionsToFile(const ConfigFileName: string); procedure AddProjectOptions(const ProjectFileName, DCPPath: string); function Compile(const ProjectFileName: string): Boolean; function GetConfigFileName: string; virtual; public function Execute(const CommandLine: string): Boolean; override; function MakePackage(const PackageName, BPLPath, DCPPath: string; ExtraOptions: string = ''): Boolean; function MakeProject(const ProjectName, OutputDir, DcpSearchPath: string; ExtraOptions: string = ''): Boolean; procedure SetDefaultOptions; virtual; {$IFDEF KEEP_DEPRECATED} function SupportsLibSuffix: Boolean; {$ENDIF KEEP_DEPRECATED} property OnBeforeSaveOptionsToFile: TNotifyEvent read FOnBeforeSaveOptionsToFile write FOnBeforeSaveOptionsToFile; property ConfigFileName: string read GetConfigFileName; end; {$IFDEF KEEP_DEPRECATED} TJclDCC = TJclDCC32; {$ENDIF KEEP_DEPRECATED} TJclBpr2Mak = class(TJclBorlandCommandLineTool) protected function GetExeName: string; override; end; TJclBorlandMake = class(TJclBorlandCommandLineTool) protected function GetExeName: string; override; end; TJclBorRADToolPalette = class(TJclBorRADToolInstallationObject) private FKey: string; FTabNames: TStringList; function GetComponentsOnTab(Index: Integer): string; function GetHiddenComponentsOnTab(Index: Integer): string; function GetTabNameCount: Integer; function GetTabNames(Index: Integer): string; procedure ReadTabNames; protected constructor Create(AInstallation: TJclBorRADToolInstallation); public destructor Destroy; override; procedure ComponentsOnTabToStrings(Index: Integer; Strings: TStrings; IncludeUnitName: Boolean = False; IncludeHiddenComponents: Boolean = True); function DeleteTabName(const TabName: string): Boolean; function TabNameExists(const TabName: string): Boolean; property ComponentsOnTab[Index: Integer]: string read GetComponentsOnTab; property HiddenComponentsOnTab[Index: Integer]: string read GetHiddenComponentsOnTab; property Key: string read FKey; property TabNames[Index: Integer]: string read GetTabNames; property TabNameCount: Integer read GetTabNameCount; end; TJclBorRADToolRepository = class(TJclBorRADToolInstallationObject) private FIniFile: TIniFile; FFileName: string; FPages: TStringList; function GetIniFile: TIniFile; function GetPages: TStrings; protected constructor Create(AInstallation: TJclBorRADToolInstallation); public destructor Destroy; override; procedure AddObject(const FileName, ObjectType, PageName, ObjectName, IconFileName, Description, Author, Designer: string; const Ancestor: string = ''); procedure CloseIniFile; function FindPage(const Name: string; OptionalIndex: Integer): string; procedure RemoveObjects(const PartialPath, FileName, ObjectType: string); property FileName: string read FFileName; property IniFile: TIniFile read GetIniFile; property Pages: TStrings read GetPages; end; TCommandLineTool = (clAsm, clBcc32, clDcc32, clDccIL, clMake, clProj2Mak); TCommandLineTools = set of TCommandLineTool; TJclBorRADToolInstallationClass = class of TJclBorRADToolInstallation; TJclBorRADToolInstallation = class(TObject) private FConfigData: TCustomIniFile; FConfigDataLocation: string; FGlobals: TStringList; FRootDir: string; FBinFolderName: string; FBCC32: TJclBCC32; FDCC32: TJclDCC32; FBpr2Mak: TJclBpr2Mak; FMake: IJclCommandLineTool; FEditionStr: string; FEdition: TJclBorRADToolEdition; FEnvironmentVariables: TStringList; FIdePackages: TJclBorRADToolIdePackages; FIdeTools: TJclBorRADToolIdeTool; FInstalledUpdatePack: Integer; {$IFDEF MSWINDOWS} FOpenHelp: TJclBorlandOpenHelp; {$ENDIF MSWINDOWS} FPalette: TJclBorRADToolPalette; FRepository: TJclBorRADToolRepository; FVersionNumber: Integer; // Delphi 2005: 3 - Delphi 7: 7 - Delphi 2007: 11 FVersionNumberStr: string; FIDEVersionNumber: Integer; // Delphi 2005: 3 - Delphi 7: 7 - Delphi 2007: 11 FIDEVersionNumberStr: string; FMapCreate: Boolean; {$IFDEF MSWINDOWS} FJdbgCreate: Boolean; FJdbgInsert: Boolean; FMapDelete: Boolean; {$ENDIF MSWINDOWS} FCommandLineTools: TCommandLineTools; FPersonalities: TJclBorPersonalities; FOutputCallback: TTextHandler; function GetSupportsLibSuffix: Boolean; function GetBCC32: TJclBCC32; function GetDCC32: TJclDCC32; function GetBpr2Mak: TJclBpr2Mak; function GetMake: IJclCommandLineTool; function GetDescription: string; function GetEditionAsText: string; function GetIdeExeFileName: string; function GetGlobals: TStrings; function GetIdeExeBuildNumber: string; function GetIdePackages: TJclBorRADToolIdePackages; function GetIsTurboExplorer: Boolean; function GetLatestUpdatePack: Integer; function GetPalette: TJclBorRADToolPalette; function GetRepository: TJclBorRADToolRepository; function GetUpdateNeeded: Boolean; protected constructor Create(const AConfigDataLocation: string); virtual; function ProcessMapFile(const BinaryFileName: string): Boolean; // compilation functions function CompileDelphiPackage(const PackageName, BPLPath, DCPPath: string): Boolean; overload; virtual; function CompileDelphiPackage(const PackageName, BPLPath, DCPPath, ExtraOptions: string): Boolean; overload; virtual; function CompileDelphiProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; virtual; function CompileBCBPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function CompileBCBProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; virtual; // installation (=compilation+registration) / uninstallation(=unregistration+deletion) functions function InstallDelphiPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function UninstallDelphiPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function InstallBCBPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function UninstallBCBPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function InstallDelphiIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function UninstallDelphiIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function InstallBCBIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function UninstallBCBIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function InstallDelphiExpert(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; virtual; function UninstallDelphiExpert(const ProjectName, OutputDir: string): Boolean; virtual; function InstallBCBExpert(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; virtual; function UninstallBCBExpert(const ProjectName, OutputDir: string): Boolean; virtual; procedure ReadInformation; //function AddMissingPathItems(var Path: string; const NewPath: string): Boolean; function RemoveFromPath(var Path: string; const ItemsToRemove: string): Boolean; function GetDCPOutputPath: string; virtual; function GetBPLOutputPath: string; virtual; function GetEnvironmentVariables: TStrings; virtual; function GetVclIncludeDir: string; virtual; function GetName: string; virtual; procedure OutputString(const AText: string); function OutputFileDelete(const FileName: string): Boolean; procedure SetOutputCallback(const Value: TTextHandler); virtual; function GetDebugDCUPath: TJclBorRADToolPath; virtual; procedure SetDebugDCUPath(const Value: TJclBorRADToolPath); virtual; function GetLibrarySearchPath: TJclBorRADToolPath; virtual; procedure SetLibrarySearchPath(const Value: TJclBorRADToolPath); virtual; function GetLibraryBrowsingPath: TJclBorRADToolPath; virtual; procedure SetLibraryBrowsingPath(const Value: TJclBorRADToolPath); virtual; function GetValid: Boolean; virtual; public destructor Destroy; override; class procedure ExtractPaths(const Path: TJclBorRADToolPath; List: TStrings); class function GetLatestUpdatePackForVersion(Version: Integer): Integer; virtual; class function PackageSourceFileExtension: string; virtual; class function ProjectSourceFileExtension: string; virtual; class function RadToolKind: TJclBorRadToolKind; virtual; {class} function RadToolName: string; virtual; function AnyInstanceRunning: Boolean; function AddToDebugDCUPath(const Path: string): Boolean; function AddToLibrarySearchPath(const Path: string): Boolean; function AddToLibraryBrowsingPath(const Path: string): Boolean; {$IFDEF KYLIX} function ConfigFileName(const Extension: string): string; virtual; {$ENDIF KYLIX} function FindFolderInPath(Folder: string; List: TStrings): Integer; // package functions // install = package compile + registration // uninstall = unregistration + deletion function CompilePackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function InstallPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function UninstallPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function InstallIDEPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; function UninstallIDEPackage(const PackageName, BPLPath, DCPPath: string): Boolean; virtual; // project functions function CompileProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; virtual; // expert functions // install = project compile + registration // uninstall = unregistration + deletion function InstallExpert(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; virtual; function UninstallExpert(const ProjectName, OutputDir: string): Boolean; virtual; // registration/unregistration functions function RegisterPackage(const BinaryFileName, Description: string): Boolean; virtual; function UnregisterPackage(const BinaryFileName: string): Boolean; virtual; function RegisterIDEPackage(const BinaryFileName, Description: string): Boolean; virtual; function UnregisterIDEPackage(const BinaryFileName: string): Boolean; virtual; function RegisterExpert(const BinaryFileName, Description: string): Boolean; virtual; function UnregisterExpert(const BinaryFileName: string): Boolean; virtual; {$IFDEF KEEP_DEPRECATED} function IsBDSPersonality: Boolean; {$ENDIF KEEP_DEPRECATED} function GetDefaultProjectsDir: string; virtual; function GetCommonProjectsDir: string; virtual; function RemoveFromDebugDCUPath(const Path: string): Boolean; function RemoveFromLibrarySearchPath(const Path: string): Boolean; function RemoveFromLibraryBrowsingPath(const Path: string): Boolean; function SubstitutePath(const Path: string): string; {$IFDEF KEEP_DEPRECATED} function SupportsBCB: Boolean; {$ENDIF KEEP_DEPRECATED} function SupportsVisualCLX: Boolean; function SupportsVCL: Boolean; function LibFolderName: string; // Command line tools property CommandLineTools: TCommandLineTools read FCommandLineTools; property BCC32: TJclBCC32 read GetBCC32; property DCC32: TJclDCC32 read GetDCC32; property Bpr2Mak: TJclBpr2Mak read GetBpr2Mak; property Make: IJclCommandLineTool read GetMake; // Paths property BinFolderName: string read FBinFolderName; property BPLOutputPath: string read GetBPLOutputPath; property DebugDCUPath: TJclBorRADToolPath read GetDebugDCUPath write SetDebugDCUPath; property DCPOutputPath: string read GetDCPOutputPath; property DefaultProjectsDir: string read GetDefaultProjectsDir; property CommonProjectsDir: string read GetCommonProjectsDir; // property Description: string read GetDescription; property Edition: TJclBorRADToolEdition read FEdition; property EditionAsText: string read GetEditionAsText; property EnvironmentVariables: TStrings read GetEnvironmentVariables; property IdePackages: TJclBorRADToolIdePackages read GetIdePackages; property IdeTools: TJclBorRADToolIdeTool read FIdeTools; property IdeExeBuildNumber: string read GetIdeExeBuildNumber; property IdeExeFileName: string read GetIdeExeFileName; property InstalledUpdatePack: Integer read FInstalledUpdatePack; property LatestUpdatePack: Integer read GetLatestUpdatePack; property LibrarySearchPath: TJclBorRADToolPath read GetLibrarySearchPath write SetLibrarySearchPath; property LibraryBrowsingPath: TJclBorRADToolPath read GetLibraryBrowsingPath write SetLibraryBrowsingPath; {$IFDEF MSWINDOWS} property OpenHelp: TJclBorlandOpenHelp read FOpenHelp; {$ENDIF MSWINDOWS} property MapCreate: Boolean read FMapCreate write FMapCreate; {$IFDEF MSWINDOWS} property JdbgCreate: Boolean read FJdbgCreate write FJdbgCreate; property JdbgInsert: Boolean read FJdbgInsert write FJdbgInsert; property MapDelete: Boolean read FMapDelete write FMapDelete; {$ENDIF MSWINDOWS} property ConfigData: TCustomIniFile read FConfigData; property ConfigDataLocation: string read FConfigDataLocation; property Globals: TStrings read GetGlobals; property Name: string read GetName; property Palette: TJclBorRADToolPalette read GetPalette; property Repository: TJclBorRADToolRepository read GetRepository; property RootDir: string read FRootDir; property UpdateNeeded: Boolean read GetUpdateNeeded; property Valid: Boolean read GetValid; property VclIncludeDir: string read GetVclIncludeDir; property IDEVersionNumber: Integer read FIDEVersionNumber; property IDEVersionNumberStr: string read FIDEVersionNumberStr; property VersionNumber: Integer read FVersionNumber; property VersionNumberStr: string read FVersionNumberStr; property Personalities: TJclBorPersonalities read FPersonalities; {$IFDEF KEEP_DEPRECATED} property DCC: TJclDCC32 read GetDCC32; {$ENDIF KEEP_DEPRECATED} property SupportsLibSuffix: Boolean read GetSupportsLibSuffix; property OutputCallback: TTextHandler read FOutputCallback write SetOutputCallback; property IsTurboExplorer: Boolean read GetIsTurboExplorer; end; TJclBCBInstallation = class(TJclBorRADToolInstallation) protected constructor Create(const AConfigDataLocation: string); override; function GetEnvironmentVariables: TStrings; override; public destructor Destroy; override; class function PackageSourceFileExtension: string; override; class function ProjectSourceFileExtension: string; override; class function RadToolKind: TJclBorRadToolKind; override; {class }function RadToolName: string; override; class function GetLatestUpdatePackForVersion(Version: Integer): Integer; override; {$IFDEF KYLIX} function ConfigFileName(const Extension: string): string; override; {$ENDIF KYLIX} end; TJclDelphiInstallation = class(TJclBorRADToolInstallation) protected constructor Create(const AConfigDataLocation: string); override; function GetEnvironmentVariables: TStrings; override; public destructor Destroy; override; class function PackageSourceFileExtension: string; override; class function ProjectSourceFileExtension: string; override; class function RadToolKind: TJclBorRadToolKind; override; class function GetLatestUpdatePackForVersion(Version: Integer): Integer; override; function InstallPackage(const PackageName, BPLPath, DCPPath: string): Boolean; reintroduce; {class }function RadToolName: string; override; {$IFDEF KYLIX} function ConfigFileName(const Extension: string): string; override; {$ENDIF KYLIX} end; {$IFDEF MSWINDOWS} TJclDCCIL = class(TJclDCC32) private FMaxCLRVersion: string; protected function GetExeName: string; override; function GetConfigFileName: string; override; function GetMaxCLRVersion: string; public function MakeProject(const ProjectName, OutputDir, ExtraOptions: string): Boolean; reintroduce; procedure SetDefaultOptions; override; property MaxCLRVersion: string read GetMaxCLRVersion; end; TJclBDSInstallation = class(TJclBorRADToolInstallation) private FDualPackageInstallation: Boolean; FHelp2Manager: TJclHelp2Manager; FDCCIL: TJclDCCIL; FPdbCreate: Boolean; procedure SetDualPackageInstallation(const Value: Boolean); function GetCppPathsKeyName: string; function GetCppBrowsingPath: TJclBorRADToolPath; function GetCppSearchPath: TJclBorRADToolPath; function GetCppLibraryPath: TJclBorRADToolPath; procedure SetCppBrowsingPath(const Value: TJclBorRADToolPath); procedure SetCppSearchPath(const Value: TJclBorRADToolPath); procedure SetCppLibraryPath(const Value: TJclBorRADToolPath); function GetMaxDelphiCLRVersion: string; function GetMsBuildEnvOptionsFileName: string; function GetMsBuildEnvOption(const OptionName: string): string; procedure SetMsBuildEnvOption(const OptionName, Value: string); protected constructor Create(const AConfigDataLocation: string); override; function GetDCPOutputPath: string; override; function GetBPLOutputPath: string; override; function GetEnvironmentVariables: TStrings; override; function CompileDelphiPackage(const PackageName, BPLPath, DCPPath, ExtraOptions: string): Boolean; override; function CompileDelphiProject(const ProjectName, OutputDir: string; const DcpSearchPath: string): Boolean; override; function GetVclIncludeDir: string; override; function GetName: string; override; procedure SetOutputCallback(const Value: TTextHandler); override; function GetDebugDCUPath: TJclBorRADToolPath; override; procedure SetDebugDCUPath(const Value: TJclBorRADToolPath); override; function GetLibrarySearchPath: TJclBorRADToolPath; override; procedure SetLibrarySearchPath(const Value: TJclBorRADToolPath); override; function GetLibraryBrowsingPath: TJclBorRADToolPath; override; procedure SetLibraryBrowsingPath(const Value: TJclBorRADToolPath); override; function GetValid: Boolean; override; public destructor Destroy; override; class function PackageSourceFileExtension: string; override; class function ProjectSourceFileExtension: string; override; class function RadToolKind: TJclBorRadToolKind; override; class function GetLatestUpdatePackForVersion(Version: Integer): Integer; override; function GetDefaultProjectsDir: string; override; function GetCommonProjectsDir: string; override; {class }function RadToolName: string; override; function AddToCppSearchPath(const Path: string): Boolean; function AddToCppBrowsingPath(const Path: string): Boolean; function AddToCppLibraryPath(const Path: string): Boolean; function RemoveFromCppSearchPath(const Path: string): Boolean; function RemoveFromCppBrowsingPath(const Path: string): Boolean; function RemoveFromCppLibraryPath(const Path: string): Boolean; property CppSearchPath: TJclBorRADToolPath read GetCppSearchPath write SetCppSearchPath; property CppBrowsingPath: TJclBorRADToolPath read GetCppBrowsingPath write SetCppBrowsingPath; property CppLibraryPath: TJclBorRADToolPath read GetCppLibraryPath write SetCppLibraryPath; // Only exists in BDS 5 and upper function RegisterPackage(const BinaryFileName, Description: string): Boolean; override; function UnregisterPackage(const BinaryFileName: string): Boolean; override; function CleanPackageCache(const BinaryFileName: string): Boolean; function CompileDelphiDotNetProject(const ProjectName, OutputDir: string; PEFormat: TJclBorPlatform = bp32bit; const CLRVersion: string = ''; const ExtraOptions: string = ''): Boolean; property DualPackageInstallation: Boolean read FDualPackageInstallation write SetDualPackageInstallation; property Help2Manager: TJclHelp2Manager read FHelp2Manager; property DCCIL: TJclDCCIL read FDCCIL; property MaxDelphiCLRVersion: string read GetMaxDelphiCLRVersion; property PdbCreate: Boolean read FPdbCreate write FPdbCreate; end; {$ENDIF MSWINDOWS} TTraverseMethod = function (Installation: TJclBorRADToolInstallation): Boolean of object; TJclBorRADToolInstallations = class(TObject) private FList: TObjectList; function GetBDSInstallationFromVersion( VersionNumber: Integer): TJclBorRADToolInstallation; function GetBDSVersionInstalled(VersionNumber: Integer): Boolean; function GetCount: Integer; function GetInstallations(Index: Integer): TJclBorRADToolInstallation; function GetBCBVersionInstalled(VersionNumber: Integer): Boolean; function GetDelphiVersionInstalled(VersionNumber: Integer): Boolean; function GetBCBInstallationFromVersion(VersionNumber: Integer): TJclBorRADToolInstallation; function GetDelphiInstallationFromVersion(VersionNumber: Integer): TJclBorRADToolInstallation; protected procedure ReadInstallations; public constructor Create; destructor Destroy; override; function AnyInstanceRunning: Boolean; function AnyUpdatePackNeeded(var Text: string): Boolean; function Iterate(TraverseMethod: TTraverseMethod): Boolean; property Count: Integer read GetCount; property Installations[Index: Integer]: TJclBorRADToolInstallation read GetInstallations; default; property BCBInstallationFromVersion[VersionNumber: Integer]: TJclBorRADToolInstallation read GetBCBInstallationFromVersion; property DelphiInstallationFromVersion[VersionNumber: Integer]: TJclBorRADToolInstallation read GetDelphiInstallationFromVersion; property BDSInstallationFromVersion[VersionNumber: Integer]: TJclBorRADToolInstallation read GetBDSInstallationFromVersion; property BCBVersionInstalled[VersionNumber: Integer]: Boolean read GetBCBVersionInstalled; property DelphiVersionInstalled[VersionNumber: Integer]: Boolean read GetDelphiVersionInstalled; property BDSVersionInstalled[VersionNumber: Integer]: Boolean read GetBDSVersionInstalled; end; {$IFDEF KEEP_DEPRECATED} function BPLFileName(const BPLPath, PackageFileName: string): string; {$ENDIF KEEP_DEPRECATE} function BinaryFileName(const OutputPath, ProjectFileName: string): string; function IsDelphiPackage(const FileName: string): Boolean; function IsDelphiProject(const FileName: string): Boolean; function IsBCBPackage(const FileName: string): Boolean; function IsBCBProject(const FileName: string): Boolean; procedure GetDPRFileInfo(const DPRFileName: string; out BinaryExtension: string; const LibSuffix: PString = nil); procedure GetBPRFileInfo(const BPRFileName: string; out BinaryFileName: string; const Description: PString = nil); procedure GetDPKFileInfo(const DPKFileName: string; out RunOnly: Boolean; const LibSuffix: PString = nil; const Description: PString = nil); procedure GetBPKFileInfo(const BPKFileName: string; out RunOnly: Boolean; const BinaryFileName: PString = nil; const Description: PString = nil); {$IFDEF UNITVERSIONING} const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL: https://jcl.svn.sourceforge.net:443/svnroot/jcl/tags/JCL-1.100-Build2646/jcl/source/common/JclBorlandTools.pas $'; Revision: '$Revision: 2038 $'; Date: '$Date: 2007-06-16 20:31:47 +0200 (sam., 16 juin 2007) $'; LogPath: 'JCL\source\common' ); {$ENDIF UNITVERSIONING} implementation uses SysConst, {$IFDEF MSWINDOWS} Registry, JclRegistry, JclDebug, {$ENDIF MSWINDOWS} {$IFDEF HAS_UNIT_LIBC} Libc, {$ENDIF HAS_UNIT_LIBC} JclFileUtils, JclLogic, JclResources, JclStrings, JclSysInfo, JclSimpleXml; // Internal type TUpdatePack = record Version: Byte; LatestUpdatePack: Integer; end; {$IFDEF KYLIX} TKylixVersion = 1..3; {$ENDIF KYLIX} {$IFDEF MSWINDOWS} TBDSVersionInfo = record Name: string; VersionStr: string; Version: Integer; CoreIdeVersion: string; ProjectsDirResId1: Integer; ProjectsDirResId2: Integer; CLRVersionResId: Integer; Supported: Boolean; end; {$ENDIF MSWINDOWS} const {$IFDEF MSWINDOWS} {$IFNDEF RTL140_UP} PathSep = ';'; {$ENDIF ~RTL140_UP} MSHelpSystemKeyName = 'SOFTWARE\Microsoft\Windows\Help'; BCBKeyName = 'SOFTWARE\Borland\C++Builder'; BDSKeyName = 'SOFTWARE\Borland\BDS'; DelphiKeyName = 'SOFTWARE\Borland\Delphi'; BDSVersions: array [1..5] of TBDSVersionInfo = ( ( Name: RsCSharpName; VersionStr: '1.0'; Version: 1; CoreIdeVersion: '71'; ProjectsDirResId1: 64507; ProjectsDirResId2: 0; CLRVersionResId: 0; // no dccil.exe Supported: True), ( Name: RsDelphiName; VersionStr: '8'; Version: 8; CoreIdeVersion: '71'; ProjectsDirResId1: 64460; ProjectsDirResId2: 0; CLRVersionResId: 9499; Supported: True), ( Name: RsDelphiName; VersionStr: '2005'; Version: 9; CoreIdeVersion: '90'; ProjectsDirResId1: 64431; ProjectsDirResId2: 0; CLRVersionResId: 9499; Supported: True), ( Name: RsBDSName; VersionStr: '2006'; Version: 10; CoreIdeVersion: '100'; ProjectsDirResId1: 64719; ProjectsDirResId2: 0; CLRVersionResId: 9500; Supported: True), ( Name: RsDelphiName; VersionStr: '2007'; Version: 11; CoreIdeVersion: '100'; ProjectsDirResId1: 64396; ProjectsDirResId2: 64398; CLRVersionResId: 9500; Supported: True) ); {$ENDIF MSWINDOWS} {$IFDEF KYLIX} RootDirValueName = 'DelphiRoot'; {$ELSE} RootDirValueName = 'RootDir'; {$ENDIF KYLIX} EditionValueName = 'Edition'; VersionValueName = 'Version'; DebuggingKeyName = 'Debugging'; DebugDCUPathValueName = 'Debug DCUs Path'; GlobalsKeyName = 'Globals'; LibraryKeyName = 'Library'; LibrarySearchPathValueName = 'Search Path'; LibraryBrowsingPathValueName = 'Browsing Path'; LibraryBPLOutputValueName = 'Package DPL Output'; LibraryDCPOutputValueName = 'Package DCP Output'; BDSDebugDCUPathValueName = 'Debug DCU Path'; CppPathsKeyName = 'CppPaths'; CppPathsV5UpperKeyName = 'C++\Paths'; CppBrowsingPathValueName = 'BrowsingPath'; CppSearchPathValueName = 'SearchPath'; CppLibraryPathValueName = 'LibraryPath'; TransferKeyName = 'Transfer'; TransferCountValueName = 'Count'; TransferPathValueName = 'Path%d'; TransferParamsValueName = 'Params%d'; TransferTitleValueName = 'Title%d'; TransferWorkDirValueName = 'WorkingDir%d'; DisabledPackagesKeyName = 'Disabled Packages'; EnvVariablesKeyName = 'Environment Variables'; EnvVariableBDSValueName = 'BDS'; EnvVariableBDSPROJDIRValueName = 'BDSPROJECTSDIR'; EnvVariableBDSCOMDIRValueName = 'BDSCOMMONDIR'; KnownPackagesKeyName = 'Known Packages'; KnownIDEPackagesKeyName = 'Known IDE Packages'; ExpertsKeyName = 'Experts'; PackageCacheKeyName = 'Package Cache'; PaletteKeyName = 'Palette'; PaletteHiddenTag = '.Hidden'; ConfigurationExtension = '.cfg'; {$IFDEF MSWINDOWS} AsmExeName = 'tasm32.exe'; BCC32ExeName = 'bcc32.exe'; DCC32ExeName = 'dcc32.exe'; DCCILExeName = 'dccil.exe'; Bpr2MakExeName = 'bpr2mak.exe'; MakeExeName = 'make.exe'; DelphiOptionsFileExtension = '.dof'; {$IFDEF BCB} BorRADToolRepositoryFileName = 'bcb.dro'; {$ELSE BCB} BorRADToolRepositoryFileName = 'delphi32.dro'; {$ENDIF BCB} HelpContentFileName = '%s\Help\%s%d.ohc'; HelpIndexFileName = '%s\Help\%s%d.ohi'; HelpLinkFileName = '%s\Help\%s%d.ohl'; HelpProjectFileName = '%s\Help\%s%d.ohp'; HelpGidFileName = '%s\Help\%s%d.gid'; {$ENDIF MSWINDOWS} {$IFDEF MSWINDOWS} DCC32ConfigurationFile = 'DCC32.CFG'; {$ELSE MSWINDOWS} DCC32ConfigurationFile = 'dcc.conf'; {$ENDIF MSWINDOWS} DCCILConfigurationFile = 'DCCIL.CFG'; {$IFDEF KYLIX} IDs: array [TKylixVersion] of Integer = (60, 65, 69); LibSuffixes: array [TKylixVersion] of string[3] = ('6.0', '6.5', '6.9'); BCC32ExeName = 'bcc'; DCC32ExeName = 'dcc'; Bpr2MakExeName = 'bpr2mak'; MakeExeName = 'make'; DelphiIdeExeName = 'delphi'; BCBIdeExeName = 'bcblin'; DelphiOptionsFileExtension = '.kof'; KylixHelpNamePart = 'k%d'; {$ENDIF KYLIX} DelphiLibSuffixOption = '{$LIBSUFFIX '''; DelphiDescriptionOption = '{$DESCRIPTION '''; DelphiRunOnlyOption = '{$RUNONLY}'; DelphiBinaryExtOption = '{$E '; BCBLFlagsOption = ' 0 then begin SubS1 := Copy(S, LProjectPos, Length(S)); J := 1; while (Pos('>', SubS1) = 0) and ((I + J) < BPKFile.Count) do begin SubS1 := SubS1 + BPKFile[I + J]; Inc(J); end; BinaryFileNamePos := Pos('"', SubS1); if BinaryFileNamePos > 0 then begin SubS2 := Copy(SubS1, BinaryFileNamePos + 1, Length(SubS1) - BinaryFileNamePos); EndFileNamePos := Pos('"', SubS2); if EndFileNamePos > 0 then BinaryFileName := Copy(SubS2, 1, EndFileNamePos - 1); end; end; LFlagsPos := Pos(BCBLFlagsOption, S); if LFlagsPos > 0 then begin SubS1 := Copy(S, LFlagsPos, Length(S)); J := 1; while (Pos('>', SubS1) = 0) and ((I + J) < BPKFile.Count) do begin SubS1 := SubS1 + BPKFile[I + J]; Inc(J); end; DSwitchPos := Pos(BCBDSwitchOption, SubS1); if DSwitchPos > 0 then begin SubS2 := Copy(SubS1, DSwitchPos, Length(SubS1)); SemiColonPos := Pos(';', SubS2); if SemiColonPos > 0 then begin SubS3 := Copy(SubS2, SemiColonPos+1, Length(SubS2)); AmpPos := Pos('&', SubS3); if (Description <> nil) and (AmpPos > 0) then Description^ := Copy(SubS3, 1, AmpPos - 1); end; end; end; end; finally BPKFile.Free; end; end; procedure GetDPKFileInfo(const DPKFileName: string; out RunOnly: Boolean; const LibSuffix: PString = nil; const Description: PString = nil); var I: Integer; S: string; DPKFile: TStringList; begin DPKFile := TStringList.Create; try DPKFile.LoadFromFile(DPKFileName); if Assigned(Description) then Description^ := ''; if Assigned(LibSuffix) then LibSuffix^ := ''; RunOnly := False; for I := 0 to DPKFile.Count - 1 do begin S := TrimRight(DPKFile.Strings[I]); if Assigned(Description) and (Pos(DelphiDescriptionOption, S) = 1) then Description^ := Copy(S, Length(DelphiDescriptionOption), Length(S) - Length(DelphiDescriptionOption)) else if Assigned(LibSuffix) and (Pos(DelphiLibSuffixOption, S) = 1) then LibSuffix^ := StrTrimQuotes(Copy(S, Length(DelphiLibSuffixOption), Length(S) - Length(DelphiLibSuffixOption))) else if Pos(DelphiRunOnlyOption, S) = 1 then RunOnly := True; end; finally DPKFile.Free; end; end; procedure GetBPKFileInfo(const BPKFileName: string; out RunOnly: Boolean; const BinaryFileName: PString = nil; const Description: PString = nil); var I, J: Integer; S, SubS1, SubS2, SubS3: string; BPKFile: TStringList; LFlagsPos, DSwitchPos, SemiColonPos, AmpPos, GprPos: Integer; LProjectPos, BinaryFileNamePos, EndFileNamePos: Integer; begin BPKFile := TStringList.Create; try BPKFile.LoadFromFile(BPKFileName); if Assigned(Description) then Description^ := ''; if Assigned(BinaryFileName) then BinaryFileName^ := ''; RunOnly := False; for I := 0 to BPKFile.Count - 1 do begin S := BPKFile[I]; LProjectPos := Pos(BCBProjectOption, S); if Assigned(BinaryFileName) and (LProjectPos > 0) then begin SubS1 := Copy(S,LProjectPos, Length(S)); J := 1; while (Pos('>', SubS1) = 0) and ((I + J) < BPKFile.Count) do begin SubS1 := SubS1 + BPKFile[I + J]; Inc(J); end; BinaryFileNamePos := Pos('"', SubS1); if BinaryFileNamePos > 0 then begin SubS2 := Copy(SubS1, BinaryFileNamePos + 1, Length(SubS1) - BinaryFileNamePos); EndFileNamePos := Pos('"', SubS2); if EndFileNamePos > 0 then BinaryFileName^ := Copy(SubS2, 1, EndFileNamePos - 1); end; end; LFlagsPos := Pos(BCBLFlagsOption, S); if LFlagsPos > 0 then begin SubS1 := Copy(S, LFlagsPos, Length(S)); J := 1; while (Pos('>', SubS1) = 0) and ((I + J) < BPKFile.Count) do begin SubS1 := SubS1 + BPKFile[I + J]; Inc(J); end; DSwitchPos := Pos(BCBDSwitchOption, SubS1); GprPos := Pos(BCBGprSwitchOption, SubS1); if DSwitchPos > 0 then begin SubS2 := Copy(SubS1, DSwitchPos, Length(SubS1)); SemiColonPos := Pos(';', SubS2); if SemiColonPos > 0 then begin SubS3 := Copy(SubS2, SemiColonPos + 1, Length(SubS2)); AmpPos := Pos('&', SubS3); if (Description <> nil) and (AmpPos > 0) then Description^ := Copy(SubS3, 1, AmpPos - 1); end; end; if GprPos > 0 then RunOnly := True; end; end; finally BPKFile.Free; end; end; function BPLFileName(const BPLPath, PackageFileName: string): string; var PackageExtension, LibSuffix: string; RunOnly: Boolean; begin PackageExtension := ExtractFileExt(PackageFileName); if SameText(PackageExtension, SourceExtensionDelphiPackage) then begin GetDPKFileInfo(PackageFileName, RunOnly, @LibSuffix); Result := PathExtractFileNameNoExt(PackageFileName) + LibSuffix + BinaryExtensionPackage; end else if SameText(PackageExtension, SourceExtensionBCBPackage) then GetBPKFileInfo(PackageFileName, RunOnly, @Result) else raise EJclBorRadException.CreateResFmt(@RsEUnknownPackageExtension, [PackageExtension]); Result := PathAddSeparator(BPLPath) + Result; end; function BinaryFileName(const OutputPath, ProjectFileName: string): string; var ProjectExtension, LibSuffix, BinaryExtension: string; RunOnly: Boolean; begin ProjectExtension := ExtractFileExt(ProjectFileName); if SameText(ProjectExtension, SourceExtensionDelphiPackage) then begin GetDPKFileInfo(ProjectFileName, RunOnly, @LibSuffix); Result := PathExtractFileNameNoExt(ProjectFileName) + LibSuffix + BinaryExtensionPackage; end else if SameText(ProjectExtension, SourceExtensionDelphiProject) then begin GetDPRFileInfo(ProjectFileName, BinaryExtension, @LibSuffix); Result := PathExtractFileNameNoExt(ProjectFileName) + LibSuffix + BinaryExtension; end else if SameText(ProjectExtension, SourceExtensionBCBPackage) then GetBPKFileInfo(ProjectFileName, RunOnly, @Result) else if SameText(ProjectExtension, SourceExtensionBCBProject) then GetBPRFileInfo(ProjectFileName, Result) else raise EJclBorRadException.CreateResFmt(@RsEUnknownProjectExtension, [ProjectExtension]); Result := PathAddSeparator(OutputPath) + Result; end; function IsDelphiPackage(const FileName: string): Boolean; begin Result := SameText(ExtractFileExt(FileName), SourceExtensionDelphiPackage); { TODO : Add some plausibility tests } { like var F: TextFile; FirstLine: string; if FileExists(FileName) then begin AssignFile(F, FileName); Reset(F); ReadLn(F, FirstLine); Result := Pos('package ', FirstLine) = 1; CloseFile(F); end; } end; function IsDelphiProject(const FileName: string): Boolean; begin Result := SameText(ExtractFileExt(FileName), SourceExtensionDelphiProject); end; function IsBCBPackage(const FileName: string): Boolean; begin Result := SameText(ExtractFileExt(FileName), SourceExtensionBCBPackage); end; function IsBCBProject(const FileName: string): Boolean; begin Result := SameText(ExtractFileExt(FileName), SourceExtensionBCBProject); end; {$IFDEF MSWINDOWS} function LoadResStrings(const BaseBinName: string; const ResId: array of Integer): string; var H: HMODULE; LocaleName: array [0..4] of Char; FileName, ResValue: string; Index: Integer; begin Result := ''; FileName := BaseBinName; if not FileExists(FileName) then begin FillChar(LocaleName, SizeOf(LocaleName[0]), 0); GetLocaleInfo(GetThreadLocale, LOCALE_SABBREVLANGNAME, LocaleName, SizeOf(LocaleName)); if LocaleName[0] <> #0 then begin if FileExists(FileName + LocaleName) then FileName := FileName + LocaleName else begin LocaleName[2] := #0; if FileExists(FileName + LocaleName) then FileName := FileName + LocaleName else FileName := ''; end; end; end; if FileName <> '' then begin H := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE or DONT_RESOLVE_DLL_REFERENCES); if H <> 0 then try for Index := Low(ResId) to High(ResId) do begin SetLength(ResValue, 1024); SetLength(ResValue, LoadString(H, ResId[Index], PChar(ResValue), Length(ResValue) - 1)); if Result <> '' then Result := PathAddSeparator(Result) + ResValue else Result := ResValue; end; finally FreeLibrary(H); end; end; end; function RegGetValueNamesAndValues(const RootKey: HKEY; const Key: string; const List: TStrings): Boolean; var I: Integer; TempList: TStringList; Name: string; DataType: DWORD; begin TempList := TStringList.Create; try Result := RegKeyExists(RootKey, Key) and RegGetValueNames(RootKey, Key, TempList); if Result then begin for I := 0 to TempList.Count - 1 do begin Name := TempList[I]; if RegGetDataType(RootKey, Key, Name, DataType) and ((DataType = REG_SZ) or (DataType = REG_EXPAND_SZ) or (DataType = REG_BINARY)) then TempList[I] := Name + '=' + RegReadStringDef(RootKey, Key, Name, ''); end; List.AddStrings(TempList); end; finally TempList.Free; end; end; {$ENDIF MSWINDOWS} //=== { TJclBorRADToolInstallationObject } =================================== constructor TJclBorRADToolInstallationObject.Create(AInstallation: TJclBorRADToolInstallation); begin FInstallation := AInstallation; end; {$IFDEF MSWINDOWS} //=== { TJclBorlandOpenHelp } ================================================ function TJclBorlandOpenHelp.AddHelpFile(const HelpFileName, IndexName: string): Boolean; var CntFileName, HelpName, CntName: string; List: TStringList; procedure AddToList(const FileName, Text: string); var I, Attr: Integer; Found: Boolean; begin List.LoadFromFile(FileName); Found := False; for I := 0 to List.Count - 1 do if AnsiSameText(Trim(List[I]), Text) then begin Found := True; Break; end; if not Found then begin List.Add(Text); Attr := FileGetAttr(FileName); FileSetAttr(FileName, faArchive); List.SaveToFile(FileName); FileSetAttr(FileName, Attr); end; end; begin CntFileName := ChangeFileExt(HelpFileName, '.cnt'); Result := FileExists(HelpFileName) and FileExists(CntFileName); if Result then begin HelpName := ExtractFileName(HelpFileName); CntName := ExtractFileName(CntFileName); RegWriteString(HKEY_LOCAL_MACHINE, MSHelpSystemKeyName, HelpName, ExtractFilePath(HelpFileName)); RegWriteString(HKEY_LOCAL_MACHINE, MSHelpSystemKeyName, CntName, ExtractFilePath(CntFileName)); List := TStringList.Create; try AddToList(ContentFileName, Format(':Include %s', [CntName])); AddToList(LinkFileName, Format(':Link %s', [HelpName])); AddToList(IndexFileName, Format(':Index %s=%s', [IndexName, HelpName])); SetFileLastWrite(ProjectFileName, Now); FileDelete(GidFileName); finally List.Free; end; end; end; function TJclBorlandOpenHelp.GetContentFileName: string; begin Result := ReadFileName(HelpContentFileName); end; function TJclBorlandOpenHelp.GetGidFileName: string; begin Result := ReadFileName(HelpGidFileName); end; function TJclBorlandOpenHelp.GetIndexFileName: string; begin Result := ReadFileName(HelpIndexFileName); end; function TJclBorlandOpenHelp.GetLinkFileName: string; begin Result := ReadFileName(HelpLinkFileName); end; function TJclBorlandOpenHelp.GetProjectFileName: string; begin Result := ReadFileName(HelpProjectFileName); end; function TJclBorlandOpenHelp.ReadFileName(const FormatName: string): string; var S: string; begin with Installation do begin case RadToolKind of brDelphi: if VersionNumber <= 6 then S := 'delphi' else S := 'd'; brCppBuilder: S := 'bcb'; else //brBorlandDevStudio : raise EJclBorRadException.CreateRes(@RsENoOpenHelp); end; Result := Format(FormatName, [RootDir, S, VersionNumber]); end; end; function TJclBorlandOpenHelp.RemoveHelpFile(const HelpFileName, IndexName: string): Boolean; var CntFileName, HelpName, CntName: string; List: TStringList; procedure RemoveFromList(const FileName, Text: string); var I, Attr: Integer; Found: Boolean; begin List.LoadFromFile(FileName); Found := False; for I := 0 to List.Count - 1 do if AnsiSameText(Trim(List[I]), Text) then begin Found := True; List.Delete(I); Break; end; if Found then begin Attr := FileGetAttr(FileName); FileSetAttr(FileName, faArchive); List.SaveToFile(FileName); FileSetAttr(FileName, Attr); end; end; begin CntFileName := ChangeFileExt(HelpFileName, '.cnt'); Result := FileExists(HelpFileName) and FileExists(CntFileName); if Result then begin HelpName := ExtractFileName(HelpFileName); CntName := ExtractFileName(CntFileName); //RegDeleteEntry(HKEY_LOCAL_MACHINE, MSHelpSystemKeyName, HelpName); //RegDeleteEntry(HKEY_LOCAL_MACHINE, MSHelpSystemKeyName, CntName); List := TStringList.Create; try RemoveFromList(ContentFileName, Format(':Include %s', [CntName])); RemoveFromList(LinkFileName, Format(':Link %s', [HelpName])); RemoveFromList(IndexFileName, Format(':Index %s=%s', [IndexName, HelpName])); SetFileLastWrite(ProjectFileName, Now); FileDelete(GidFileName); finally List.Free; end; end; end; //== { TJclHelp2Manager } ==================================================== const Help2BorlandNameSpace = 'Borland.BDS%d'; Help2DefaultKeyWord = '_DEFAULT'; constructor TJclHelp2Manager.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); FHxRegisterSession := nil; FHxRegister := nil; FHxPlugin := nil; if Assigned(Installation) then FIdeNameSpace := Format(Help2BorlandNameSpace, [Installation.IDEVersionNumber]) else FIdeNameSpace := ''; end; constructor TJclHelp2Manager.Create; begin Create(nil); end; destructor TJclHelp2Manager.Destroy; begin FHxRegisterSession := nil; FHxRegister := nil; FHxPlugin := nil; inherited Destroy; end; function TJclHelp2Manager.CommitTransaction: Boolean; begin Result := RequireObject([hoRegisterSession]); if Result then begin try FHxRegisterSession.CommitTransaction; except Result := False; end; end; end; function TJclHelp2Manager.CreateTransaction: Boolean; begin Result := RequireObject([hoRegisterSession]); if Result then begin try FHxRegisterSession.CreateTransaction(''); except Result := False; end; end; end; function TJclHelp2Manager.GetHxPlugin: IHxPlugin; begin RequireObject([hoPlugin]); Result := FHxPlugin; end; function TJclHelp2Manager.GetHxRegister: IHxRegister; begin RequireObject([hoRegister]); Result := FHxRegister; end; function TJclHelp2Manager.GetHxRegisterSession: IHxRegisterSession; begin RequireObject([hoRegisterSession]); Result := FHxRegisterSession; end; function TJclHelp2Manager.PlugNameSpaceIn(const SourceNameSpace, TargetNameSpace: WideString): Boolean; var Help2Default: WideString; begin Result := RequireObject([hoPlugin]); if Result then begin try Help2Default := Help2DefaultKeyWord; FHxPlugin.RegisterHelpPlugIn(TargetNameSpace, Help2Default, SourceNameSpace, Help2Default, '', 0); except Result := False; end; end; end; function TJclHelp2Manager.PlugNameSpaceInBorlandHelp( const NameSpace: WideString): Boolean; begin Result := Assigned(FInstallation) and (Installation.RadToolKind = brBorlandDevStudio) and PlugNameSpaceIn(NameSpace, IdeNamespace); end; function TJclHelp2Manager.RegisterHelpFile(const NameSpace, Identifier: WideString; const LangId: Integer; const HxSFile, HxIFile: WideString): Boolean; begin Result := RequireObject([hoRegister]); if Result then begin try FHxRegister.RegisterHelpFileSet(NameSpace, Identifier, LangId, HxSFile, HxIFile, '', '', 0, 0, 0, 0); except Result := False; end; end; end; function TJclHelp2Manager.RegisterNameSpace(const Name, Collection, Description: WideString): Boolean; begin Result := RequireObject([hoRegister]); if Result then begin try FHxRegister.RegisterNamespace(Name, Collection, Description); except Result := False; end; end; end; function TJclHelp2Manager.RequireObject(HelpObjects: TJclHelp2Objects): Boolean; begin // dependencies if (hoRegister in HelpObjects) or (hoPlugin in HelpObjects) then Include(HelpObjects, hoRegisterSession); Result := True; if (hoRegisterSession in HelpObjects) and not Assigned(FHxRegisterSession) then begin try FHxRegisterSession := CoHxRegisterSession.Create; except Result := False; end; end; if Result and (hoRegister in HelpObjects) and not Assigned(FHxRegister) then begin try Result := Supports(FHxRegisterSession.GetRegistrationObject(HxRegisterSession_IHxRegister), IHxRegister, FHxRegister); except Result := False; end; end; if Result and (hoPlugin in HelpObjects) and not Assigned(FHxPlugin) then begin try Result := Supports(FHxRegisterSession.GetRegistrationObject(HxRegisterSession_IHxPlugIn), IHxPlugin, FHxPlugin); except Result := False; end; end; end; function TJclHelp2Manager.UnPlugNameSpace(const SourceNameSpace, TargetNameSpace: WideString): Boolean; var Help2Default: WideString; begin Result := RequireObject([hoPlugin]); if Result then begin try Help2Default := Help2DefaultKeyWord; FHxPlugin.RemoveHelpPlugIn(TargetNameSpace, Help2Default, SourceNameSpace, Help2Default, ''); except Result := False; end; end; end; function TJclHelp2Manager.UnPlugNameSpaceFromBorlandHelp(const NameSpace: WideString): Boolean; begin Result := Assigned(FInstallation) and (Installation.RadToolKind = brBorlandDevStudio) and UnPlugNameSpace(NameSpace, IdeNamespace); end; function TJclHelp2Manager.UnregisterHelpFile(const NameSpace, Identifier: WideString; const LangId: Integer): Boolean; begin Result := RequireObject([hoRegister]); if Result then begin try FHxRegister.RemoveHelpFile(NameSpace, Identifier, LangId); except Result := False; end; end; end; function TJclHelp2Manager.UnregisterNameSpace(const Name: WideString): Boolean; begin Result := RequireObject([hoRegister]); if Result then begin try FHxRegister.RemoveNamespace(Name); except Result := False; end; end; end; {$ENDIF MSWINDOWS} //== { TJclBorRADToolIdeTool } =============================================== constructor TJclBorRADToolIdeTool.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); FKey := TransferKeyName; end; procedure TJclBorRADToolIdeTool.CheckIndex(Index: Integer); begin if (Index < 0) or (Index >= Count) then raise EJclError.CreateRes(@RsEIndexOufOfRange); end; function TJclBorRADToolIdeTool.GetCount: Integer; begin Result := Installation.ConfigData.ReadInteger(Key, TransferCountValueName, 0); end; function TJclBorRADToolIdeTool.GetParameters(Index: Integer): string; begin CheckIndex(Index); Result := Installation.ConfigData.ReadString(Key, Format(TransferParamsValueName, [Index]), ''); end; function TJclBorRADToolIdeTool.GetPath(Index: Integer): string; begin CheckIndex(Index); Result := Installation.ConfigData.ReadString(Key, Format(TransferPathValueName, [Index]), ''); end; function TJclBorRADToolIdeTool.GetTitle(Index: Integer): string; begin CheckIndex(Index); Result := Installation.ConfigData.ReadString(Key, Format(TransferTitleValueName, [Index]), ''); end; function TJclBorRADToolIdeTool.GetWorkingDir(Index: Integer): string; begin CheckIndex(Index); Result := Installation.ConfigData.ReadString(Key, Format(TransferWorkDirValueName, [Index]), ''); end; function TJclBorRADToolIdeTool.IndexOfPath(const Value: string): Integer; var I: Integer; begin Result := -1; for I := 0 to Count - 1 do if SamePath(Path[I], Value) then begin Result := I; Break; end; end; function TJclBorRADToolIdeTool.IndexOfTitle(const Value: string): Integer; var I: Integer; begin Result := -1; for I := 0 to Count - 1 do if Title[I] = Value then begin Result := I; Break; end; end; procedure TJclBorRADToolIdeTool.RemoveIndex(const Index: Integer); var I: Integer; begin for I := Index to Count - 2 do begin Parameters[I] := Parameters[I + 1]; Path[I] := Path[I + 1]; Title[I] := Title[I + 1]; WorkingDir[Index] := WorkingDir[I + 1]; end; Count := Count - 1; end; procedure TJclBorRADToolIdeTool.SetCount(const Value: Integer); begin if Value > Count then Installation.ConfigData.WriteInteger(Key, TransferCountValueName, Value); end; procedure TJclBorRADToolIdeTool.SetParameters(Index: Integer; const Value: string); begin CheckIndex(Index); Installation.ConfigData.WriteString(Key, Format(TransferParamsValueName, [Index]), Value); end; procedure TJclBorRADToolIdeTool.SetPath(Index: Integer; const Value: string); begin CheckIndex(Index); Installation.ConfigData.WriteString(Key, Format(TransferPathValueName, [Index]), Value); end; procedure TJclBorRADToolIdeTool.SetTitle(Index: Integer; const Value: string); begin CheckIndex(Index); Installation.ConfigData.WriteString(Key, Format(TransferTitleValueName, [Index]), Value); end; procedure TJclBorRADToolIdeTool.SetWorkingDir(Index: Integer; const Value: string); begin CheckIndex(Index); Installation.ConfigData.WriteString(Key, Format(TransferWorkDirValueName, [Index]), Value); end; //=== { TJclBorRADToolIdePackages } ========================================== constructor TJclBorRADToolIdePackages.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); FDisabledPackages := TStringList.Create; FDisabledPackages.Sorted := True; FDisabledPackages.Duplicates := dupIgnore; FKnownPackages := TStringList.Create; FKnownPackages.Sorted := True; FKnownPackages.Duplicates := dupIgnore; FKnownIDEPackages := TStringList.Create; FKnownIDEPackages.Sorted := True; FKnownIDEPackages.Duplicates := dupIgnore; FExperts := TStringList.Create; FExperts.Sorted := True; FExperts.Duplicates := dupIgnore; ReadPackages; end; destructor TJclBorRADToolIdePackages.Destroy; begin FreeAndNil(FDisabledPackages); FreeAndNil(FKnownPackages); FreeAndNil(FKnownIDEPackages); FreeAndNil(FExperts); inherited Destroy; end; function TJclBorRADToolIdePackages.AddPackage(const FileName, Description: string): Boolean; begin Result := True; RemoveDisabled(FileName); Installation.ConfigData.WriteString(KnownPackagesKeyName, FileName, Description); ReadPackages; end; function TJclBorRADToolIdePackages.AddExpert(const FileName, Description: string): Boolean; begin Result := True; RemoveDisabled(FileName); Installation.ConfigData.WriteString(ExpertsKeyName, Description, FileName); ReadPackages; end; function TJclBorRADToolIdePackages.AddIDEPackage(const FileName, Description: string): Boolean; begin Result := True; RemoveDisabled(FileName); Installation.ConfigData.WriteString(KnownIDEPackagesKeyName, FileName, Description); ReadPackages; end; function TJclBorRADToolIdePackages.GetCount: Integer; begin Result := FKnownPackages.Count; end; function TJclBorRADToolIdePackages.GetExpertCount: Integer; begin Result := FExperts.Count; end; function TJclBorRADToolIdePackages.GetExpertDescriptions(Index: Integer): string; begin Result := FExperts.Names[Index]; end; function TJclBorRADToolIdePackages.GetExpertFileNames(Index: Integer): string; begin Result := PackageEntryToFileName(FExperts.Values[FExperts.Names[Index]]); end; function TJclBorRADToolIdePackages.GetIDECount: Integer; begin Result := FKnownIDEPackages.Count; end; function TJclBorRADToolIdePackages.GetPackageDescriptions(Index: Integer): string; begin Result := FKnownPackages.Values[FKnownPackages.Names[Index]]; end; function TJclBorRADToolIdePackages.GetIDEPackageDescriptions(Index: Integer): string; begin Result := FKnownPackages.Values[FKnownIDEPackages.Names[Index]]; end; function TJclBorRADToolIdePackages.GetPackageDisabled(Index: Integer): Boolean; begin Result := Boolean(FKnownPackages.Objects[Index]); end; function TJclBorRADToolIdePackages.GetPackageFileNames(Index: Integer): string; begin Result := PackageEntryToFileName(FKnownPackages.Names[Index]); end; function TJclBorRADToolIdePackages.GetIDEPackageFileNames(Index: Integer): string; begin Result := PackageEntryToFileName(FKnownIDEPackages.Names[Index]); end; function TJclBorRADToolIdePackages.PackageEntryToFileName(const Entry: string): string; begin Result := Installation.SubstitutePath(Entry); end; procedure TJclBorRADToolIdePackages.ReadPackages; var I: Integer; procedure ReadPackageList(const Name: string; List: TStringList); var ListIsSorted: Boolean; begin ListIsSorted := List.Sorted; List.Sorted := False; List.Clear; Installation.ConfigData.ReadSectionValues(Name, List); List.Sorted := ListIsSorted; end; begin if (Installation.RadToolKind = brBorlandDevStudio) then ReadPackageList(KnownIDEPackagesKeyName, FKnownIDEPackages); ReadPackageList(KnownPackagesKeyName, FKnownPackages); ReadPackageList(DisabledPackagesKeyName, FDisabledPackages); ReadPackageList(ExpertsKeyName, FExperts); for I := 0 to Count - 1 do if FDisabledPackages.IndexOfName(FKnownPackages.Names[I]) <> -1 then FKnownPackages.Objects[I] := Pointer(True); end; procedure TJclBorRADToolIdePackages.RemoveDisabled(const FileName: string); var I: Integer; begin for I := 0 to FDisabledPackages.Count - 1 do if SamePath(FileName, PackageEntryToFileName(FDisabledPackages.Names[I])) then begin Installation.ConfigData.DeleteKey(DisabledPackagesKeyName, FDisabledPackages.Names[I]); ReadPackages; Break; end; end; function TJclBorRADToolIdePackages.RemoveExpert(const FileName: string): Boolean; var I: Integer; KnownExpertDescription, KnownExpert, KnownExpertFileName: string; begin Result := False; for I := 0 to FExperts.Count - 1 do begin KnownExpertDescription := FExperts.Names[I]; KnownExpert := FExperts.Values[KnownExpertDescription]; KnownExpertFileName := PackageEntryToFileName(KnownExpert); if SamePath(FileName, KnownExpertFileName) then begin RemoveDisabled(KnownExpertFileName); Installation.ConfigData.DeleteKey(ExpertsKeyName, KnownExpertDescription); ReadPackages; Result := True; Break; end; end; end; function TJclBorRADToolIdePackages.RemovePackage(const FileName: string): Boolean; var I: Integer; KnownPackage, KnownPackageFileName: string; begin Result := False; for I := 0 to FKnownPackages.Count - 1 do begin KnownPackage := FKnownPackages.Names[I]; KnownPackageFileName := PackageEntryToFileName(KnownPackage); if SamePath(FileName, KnownPackageFileName) then begin RemoveDisabled(KnownPackageFileName); Installation.ConfigData.DeleteKey(KnownPackagesKeyName, KnownPackage); ReadPackages; Result := True; Break; end; end; end; function TJclBorRADToolIdePackages.RemoveIDEPackage(const FileName: string): Boolean; var I: Integer; KnownIDEPackage, KnownIDEPackageFileName: string; begin Result := False; for I := 0 to FKnownIDEPackages.Count - 1 do begin KnownIDEPackage := FKnownIDEPackages.Names[I]; KnownIDEPackageFileName := PackageEntryToFileName(KnownIDEPackage); if SamePath(FileName, KnownIDEPackageFileName) then begin RemoveDisabled(KnownIDEPackageFileName); Installation.ConfigData.DeleteKey(KnownIDEPackagesKeyName, KnownIDEPackage); ReadPackages; Result := True; Break; end; end; end; //=== { TJclBorlandCommandLineTool } ========================================= constructor TJclBorlandCommandLineTool.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); FOptions := TStringList.Create; end; destructor TJclBorlandCommandLineTool.Destroy; begin FreeAndNil(FOptions); inherited Destroy; end; procedure TJclBorlandCommandLineTool.AddPathOption(const Option, Path: string); var S: string; {$IFDEF MSWINDOWS} // to avoid the 126 character limit of DCC32 (and eventually other command line tools) // which shows up with misleading error messages ("Fatal: System.pas not found") or // might even cause AVs procedure ConvertToShortPathNames(var Paths: string); var List: TStringList; I: Integer; begin List := TStringList.Create; try StrToStrings(Paths, PathSep, List); for I := 0 to List.Count - 1 do List[I] := PathGetShortName(List[I]); Paths := StringsToStr(List, PathSep); finally List.Free; end; end; {$ENDIF MSWINDOWS} begin S := PathRemoveSeparator(Path); {$IFDEF MSWINDOWS} S := LowerCase(S); // file names are case insensitive ConvertToShortPathNames(S); {$ENDIF MSWINDOWS} { TODO : If we were sure that options are always case-insensitive for Borland tools, we could use UpperCase(Option) below. } S := Format('-%s"%s"', [Option, S]); // avoid duplicate entries if Options.IndexOf(S) = -1 then Options.Add(S); end; procedure TJclBorlandCommandLineTool.CheckOutputValid; begin if Assigned(FOutputCallback) then raise EJclCommandLineToolError.CreateResFmt(@RsECmdLineToolOutputInvalid, [GetExeName]); end; function TJclBorlandCommandLineTool.Execute(const CommandLine: string): Boolean; var LaunchCommand: string; begin LaunchCommand := Format('%s %s', [FileName, CommandLine]); if Assigned(FOutputCallback) then begin FOutputCallback(LaunchCommand); Result := JclSysUtils.Execute(LaunchCommand, FOutputCallback) = 0 end else Result := JclSysUtils.Execute(LaunchCommand, FOutput) = 0; end; function TJclBorlandCommandLineTool.GetExeName: string; begin Result := ''; {$IFDEF MSWINDOWS} raise EAbstractError.CreateResFmt(@SAbstractError, ['']); // BCB doesn't support abstract keyword {$ENDIF MSWINDOWS} end; function TJclBorlandCommandLineTool.GetFileName: string; begin Result := Installation.BinFolderName + GetExeName; if Pos(' ', Result) > 0 then Result := AnsiQuotedStr(Result, '"'); end; function TJclBorlandCommandLineTool.GetOptions: TStrings; begin Result := FOptions; end; function TJclBorlandCommandLineTool.GetOutput: string; begin CheckOutputValid; Result := FOutput; end; function TJclBorlandCommandLineTool.GetOutputCallback: TTextHandler; begin Result := FOutputCallback; end; procedure TJclBorlandCommandLineTool.SetOutputCallback(const CallbackMethod: TTextHandler); begin FOutputCallback := CallbackMethod; end; //=== { TJclBCC32 } ============================================================ constructor TJclBCC32.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); end; function TJclBCC32.GetExeName: string; begin Result := BCC32ExeName; end; {$IFDEF KEEP_DEPRECATED} function TJclBCC32.SupportsLibSuffix: Boolean; begin Result := Installation.SupportsLibSuffix; end; {$ENDIF KEEP_DEPRECATED} //=== { TJclDCC32 } ============================================================ procedure TJclDCC32.AddProjectOptions(const ProjectFileName, DCPPath: string); var ConfigurationFileName, OptionsFileName, BDSProjFileName, DProjFileName, ProjectConfiguration, ProjectPlatform: string; PersonalityName, UnitOutputDir, SearchPath, DynamicPackages, SearchDcpPath, Conditionals: string; OptionsFile: TIniFile; OptionsXmlFile: TJclSimpleXML; PersonalityInfoNode, OptionNode, ChildNode, PersonalityNode, DirectoriesNode, ProjectExtensionsNode, PropertyGroupNode: TJclSimpleXMLElem; NameProperty, ConditionProperty: TJclSimpleXMLProp; FoundOptions, UsePackages: Boolean; NodeIndex: Integer; begin ConfigurationFileName := ChangeFileExt(ProjectFileName, ConfigurationExtension); if FileExists(ConfigurationFileName) then FileDelete(ConfigurationFileName); FoundOptions := False; UsePackages := False; UnitOutputDir := ''; SearchPath := ''; DynamicPackages := ''; SearchDcpPath := ''; Conditionals := ''; DProjFileName := ChangeFileExt(ProjectFileName, SourceExtensionDProject); if FileExists(DProjFileName) and (Installation.IDEVersionNumber >= 5) and (Installation.RadToolKind = brBorlandDevStudio) then begin OptionsXmlFile := TJclSimpleXML.Create; try OptionsXmlFile.LoadFromFile(DProjFileName); OptionsXmlFile.Options := OptionsXmlFile.Options - [sxoAutoCreate]; PersonalityName := ''; ProjectExtensionsNode := OptionsXmlFile.Root.Items.ItemNamed[DProjProjectExtensionsNodeName]; if Assigned(ProjectExtensionsNode) then begin PersonalityNode := ProjectExtensionsNode.Items.ItemNamed[DProjPersonalityNodeName]; if Assigned(PersonalityNode) then PersonalityName := PersonalityNode.Value; end; if AnsiSameText(PersonalityName, DProjDelphiPersonalityValue) then begin ProjectConfiguration := ''; ProjectPlatform := ''; for NodeIndex := 0 to OptionsXmlFile.Root.Items.Count - 1 do begin PropertyGroupNode := OptionsXmlFile.Root.Items.Item[NodeIndex]; if AnsiSameText(PropertyGroupNode.Name, DProjPropertyGroupNodeName) then begin ConditionProperty := PropertyGroupNode.Properties.ItemNamed[DProjConditionValueName]; if Assigned(ConditionProperty) then begin if (ProjectConfiguration <> '') and (ProjectPlatform <> '') and (AnsiPos(Format('%s|%s', [ProjectConfiguration, ProjectPlatform]), ConditionProperty.Value) > 0) then begin // this is the active configuration, check for overrides ChildNode := PropertyGroupNode.Items.ItemNamed[DProjUsePackageNodeName]; if Assigned(ChildNode) then DynamicPackages := ChildNode.Value; UsePackages := DynamicPackages <> ''; ChildNode := PropertyGroupNode.Items.ItemNamed[DProjDcuOutputDirNodeName]; if Assigned(ChildNode) then UnitOutputDir := ChildNode.Value; ChildNode := PropertyGroupNode.Items.ItemNamed[DProjUnitSearchPathNodeName]; if Assigned(ChildNode) then SearchPath := ChildNode.Value; ChildNode := PropertyGroupNode.Items.ItemNamed[DProjDefineNodeName]; if Assigned(ChildNode) then Conditionals := ChildNode.Value; end; end else begin // check for default configurations ChildNode := PropertyGroupNode.Items.ItemNamed[DProjConfigurationNodeName]; if Assigned(ChildNode) then ProjectConfiguration := ChildNode.Value; ChildNode := PropertyGroupNode.Items.ItemNamed[DProjPlatformNodeName]; if Assigned(ChildNode) then ProjectPlatform := ChildNode.Value; end; end; end; end; finally OptionsXmlFile.Free; end; FoundOptions := True; end; BDSProjFileName := ChangeFileExt(ProjectFileName, SourceExtensionBDSProject); if FileExists(BDSProjFileName) and not FoundOptions then begin OptionsXmlFile := TJclSimpleXML.Create; try OptionsXmlFile.LoadFromFile(BDSProjFileName); OptionsXmlFile.Options := OptionsXmlFile.Options - [sxoAutoCreate]; PersonalityInfoNode := OptionsXmlFile.Root.Items.ItemNamed[BDSProjPersonalityInfoNodeName]; PersonalityName := ''; if Assigned(PersonalityInfoNode) then begin OptionNode := PersonalityInfoNode.Items.ItemNamed[BDSProjOptionNodeName]; if Assigned(OptionNode) then for NodeIndex := 0 to OptionNode.Items.Count - 1 do begin ChildNode := OptionNode.Items.Item[NodeIndex]; if SameText(ChildNode.Name, BDSProjOptionNodeName) then begin NameProperty := ChildNode.Properties.ItemNamed[BDSProjNameProperty]; if Assigned(NameProperty) and SameText(NameProperty.Value, BDSProjPersonalityValue) then begin PersonalityName := ChildNode.Value; Break; end; end; end; end; if PersonalityName <> '' then begin PersonalityNode := OptionsXmlFile.Root.Items.ItemNamed[PersonalityName]; if Assigned(PersonalityNode) then begin DirectoriesNode := PersonalityNode.Items.ItemNamed[BDSProjDirectoriesNodeName]; if Assigned(DirectoriesNode) then for NodeIndex := 0 to DirectoriesNode.Items.Count - 1 do begin ChildNode := DirectoriesNode.Items.Item[NodeIndex]; if SameText(ChildNode.Name, BDSProjDirectoriesNodeName) then begin NameProperty := ChildNode.Properties.ItemNamed[BDSProjNameProperty]; if Assigned(NameProperty) then begin if SameText(NameProperty.Value, BDSProjUnitOutputDirValue) then UnitOutputDir := ChildNode.Value else if SameText(NameProperty.Value, BDSProjSearchPathValue) then SearchPath := ChildNode.Value else if SameText(NameProperty.Value, BDSProjPackagesValue) then DynamicPackages := ChildNode.Value else if SameText(NameProperty.Value, BDSProjConditionalsValue) then Conditionals := ChildNode.Value else if SameText(NameProperty.Value, BDSProjUsePackagesValue) then UsePackages := StrToBoolean(ChildNode.Value); end; end; end; end; end; finally OptionsXmlFile.Free; end; FoundOptions := True; end; OptionsFileName := ChangeFileExt(ProjectFileName, DelphiOptionsFileExtension); if FileExists(OptionsFileName) and not FoundOptions then begin OptionsFile := TIniFile.Create(OptionsFileName); try SearchPath := OptionsFile.ReadString(DOFDirectoriesSection, DOFSearchPathName, ''); UnitOutputDir := OptionsFile.ReadString(DOFDirectoriesSection, DOFUnitOutputDirKey, ''); Conditionals := OptionsFile.ReadString(DOFDirectoriesSection, DOFConditionals, ''); UsePackages := OptionsFile.ReadString(DOFCompilerSection,DOFPackageNoLinkKey,'') = '1'; DynamicPackages := OptionsFile.ReadString(DOFLinkerSection, DOFPackagesKey, ''); finally OptionsFile.Free; end; end; if UnitOutputDir <> '' then AddPathOption('N', UnitOutputDir); if SearchPath <> '' then begin AddPathOption('I', SearchPath); AddPathOption('R', SearchPath); end; if Conditionals <> '' then Options.Add(Format('-D%s', [Conditionals])); if SamePath(DCPPath, Installation.DCPOutputPath) then SearchDcpPath := DCPPath else SearchDcpPath := StrEnsureSuffix(PathSep, DCPPath) + Installation.DCPOutputPath; AddPathOption('U', StrEnsureSuffix(PathSep, SearchDcpPath) + SearchPath); if UsePackages and (DynamicPackages <> '') then Options.Add(Format('-LU"%s"',[DynamicPackages])); end; function TJclDCC32.Compile(const ProjectFileName: string): Boolean; begin // Note: PathGetShortName may not return the short path if it's a network // drive. Hence we always double quote the path, regardless of the compiling // environment. Result := Execute(StrDoubleQuote(StrTrimQuotes(ProjectFileName))); end; constructor TJclDCC32.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); SetDefaultOptions; // in case $(DELPHI)\bin\dcc32.cfg (replace as appropriate) is invalid end; function TJclDCC32.Execute(const CommandLine: string): Boolean; begin FOutput := ''; SaveOptionsToFile(ConfigFileName); Result := inherited Execute(CommandLine); FileDelete(ConfigFileName); end; function TJclDCC32.GetConfigFileName: string; begin Result := DCC32ConfigurationFile; end; procedure TJclDCC32.SaveOptionsToFile(const ConfigFileName: string); {$IFDEF MSWINDOWS} var I, J: Integer; List: TStringList; S: string; F: TextFile; function IsPathOption(const S: string; out Len: Integer): Boolean; begin Result := False; if Length(S) >= 2 then case UpCase(S[2]) of 'E', 'I', 'O', 'R', 'U': begin Result := True; Len := 2; end; 'L': if Length(S) >= 3 then begin Result := UpCase(S[3]) in ['E', 'N']; Len := 3; end; 'N': begin Result := True; if (Length(S) >= 3) and (S[3] in ['0'..'9']) then Len := 3 else Len := 2; end; end; end; begin if Assigned(FOnBeforeSaveOptionsToFile) then FOnBeforeSaveOptionsToFile(Self); AssignFile(F, ConfigFileName); Rewrite(F); List := TStringList.Create; try for I := 0 to Options.Count - 1 do begin S := Options[I]; if IsPathOption(S, J) then begin Write(F, Copy(S, 1, J), '"'); StrToStrings(StrTrimQuotes(PChar(@S[J + 1])), PathSep, List); // change to relative paths to avoid DCC32 126 character path limit for J := 0 to List.Count - 1 do List[J] := PathGetRelativePath(GetCurrentFolder, ExpandFileName(List[J])); if List.Count > 0 then begin for J := 0 to List.Count - 2 do Write(F, List[J], PathSep); Write(F, List[List.Count - 1]); end; Writeln(F, '"'); end else Writeln(F, S); end; finally List.Free; end; CloseFile(F); end; {$ENDIF MSWINDOWS} {$IFDEF UNIX} begin FOptions.SaveToFile(ConfigFileName); end; {$ENDIF UNIX} function TJclDCC32.GetExeName: string; begin Result := DCC32ExeName; end; function TJclDCC32.MakePackage(const PackageName, BPLPath, DCPPath: string; ExtraOptions: string): Boolean; var SaveDir: string; begin SaveDir := GetCurrentDir; SetCurrentDir(ExtractFilePath(PackageName) + '.'); try Options.Clear; SetDefaultOptions; AddProjectOptions(PackageName, DCPPath); AddPathOption('LN', DCPPath); AddPathOption('LE', BPLPath); Options.Add(ExtraOptions); Result := Compile(PackageName); finally SetCurrentDir(SaveDir); end; end; function TJclDCC32.MakeProject(const ProjectName, OutputDir, DcpSearchPath: string; ExtraOptions: string): Boolean; var SaveDir: string; begin SaveDir := GetCurrentDir; SetCurrentDir(ExtractFilePath(ProjectName) + '.'); try Options.Clear; SetDefaultOptions; AddProjectOptions(ProjectName, DcpSearchPath); AddPathOption('E', OutputDir); Options.Add(ExtraOptions); Result := Compile(ProjectName); finally SetCurrentDir(SaveDir); end; end; procedure TJclDCC32.SetDefaultOptions; begin Options.Clear; AddPathOption('U', Installation.LibFolderName); if Installation.RadToolKind = brCppBuilder then begin AddPathOption('U', Installation.LibFolderName + PathAddSeparator('obj')); {$IFNDEF KYLIX} if (Installation.RadToolKind <> brBorlandDevStudio) and (Installation.VersionNumber = 5) then Options.Add('-LUvcl50') else Options.Add('-LUrtl'); {$ENDIF ~KYLIX} end; end; {$IFDEF KEEP_DEPRECATED} function TJclDCC32.SupportsLibSuffix: Boolean; begin Result := Installation.SupportsLibSuffix; end; {$ENDIF KEEP_DEPRECATED} {$IFDEF MSWINDOWS} //=== { TJclDCCIL } ========================================================== function TJclDCCIL.GetConfigFileName: string; begin Result := DCCILConfigurationFile; end; function TJclDCCIL.GetExeName: string; begin Result := DCCILExeName; end; function TJclDCCIL.GetMaxCLRVersion: string; var StartPos, EndPos: Integer; begin if FMaxCLRVersion <> '' then begin Result := FMaxCLRVersion; Exit; end; Result := LoadResStrings(Installation.BinFolderName + GetExeName, [BDSVersions[Installation.IDEVersionNumber].CLRVersionResId]); StartPos := Pos(':', Result); if StartPos = 0 then StartPos := Pos('=', Result); if StartPos > 0 then Result := Copy(Result, StartPos + 1, Length(Result) - StartPos); EndPos := Pos(' ', Result); if EndPos > 0 then SetLength(Result, EndPos - 1); if Result = '' then Result := 'v1.1.4322'; // do not localize FMaxCLRVersion := Result; end; function TJclDCCIL.MakeProject(const ProjectName, OutputDir, ExtraOptions: string): Boolean; var SaveDir: string; begin SaveDir := GetCurrentDir; SetCurrentDir(ExtractFilePath(ProjectName) + '.'); try Options.Clear; SetDefaultOptions; AddProjectOptions(ProjectName, ''); AddPathOption('E', OutputDir); Options.Add(ExtraOptions); Result := Compile(ProjectName); finally SetCurrentDir(SaveDir); end; end; procedure TJclDCCIL.SetDefaultOptions; begin Options.Clear; AddPathOption('U', Installation.LibFolderName); end; {$ENDIF MSWINDOWS} //=== { TJclBorlandMake } ==================================================== function TJclBorlandMake.GetExeName: string; begin Result := MakeExeName; end; //=== { TJclBpr2Mak } ======================================================== function TJclBpr2Mak.GetExeName: string; begin Result := Bpr2MakExeName; end; //=== { TJclBorRADToolPalette } ============================================== constructor TJclBorRADToolPalette.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); FKey := PaletteKeyName; FTabNames := TStringList.Create; FTabNames.Sorted := True; ReadTabNames; end; destructor TJclBorRADToolPalette.Destroy; begin FreeAndNil(FTabNames); inherited Destroy; end; procedure TJclBorRADToolPalette.ComponentsOnTabToStrings(Index: Integer; Strings: TStrings; IncludeUnitName: Boolean; IncludeHiddenComponents: Boolean); var TempList: TStringList; procedure ProcessList(Hidden: Boolean); var D, I: Integer; List, S: string; begin if Hidden then List := HiddenComponentsOnTab[Index] else List := ComponentsOnTab[Index]; List := StrEnsureSuffix(';', List); while Length(List) > 1 do begin D := Pos(';', List); S := Trim(Copy(List, 1, D - 1)); if not IncludeUnitName then Delete(S, 1, Pos('.', S)); if Hidden then begin I := TempList.IndexOf(S); if I = -1 then TempList.AddObject(S, Pointer(True)) else TempList.Objects[I] := Pointer(True); end else TempList.Add(S); Delete(List, 1, D); end; end; begin TempList := TStringList.Create; try TempList.Duplicates := dupError; ProcessList(False); TempList.Sorted := True; if IncludeHiddenComponents then ProcessList(True); Strings.AddStrings(TempList); finally TempList.Free; end; end; function TJclBorRADToolPalette.DeleteTabName(const TabName: string): Boolean; var I: Integer; begin I := FTabNames.IndexOf(TabName); Result := I >= 0; if Result then begin Installation.ConfigData.DeleteKey(Key, FTabNames[I]); Installation.ConfigData.DeleteKey(Key, FTabNames[I] + PaletteHiddenTag); FTabNames.Delete(I); end; end; function TJclBorRADToolPalette.GetComponentsOnTab(Index: Integer): string; begin Result := Installation.ConfigData.ReadString(Key, FTabNames[Index], ''); end; function TJclBorRADToolPalette.GetHiddenComponentsOnTab(Index: Integer): string; begin Result := Installation.ConfigData.ReadString(Key, FTabNames[Index] + PaletteHiddenTag, ''); end; function TJclBorRADToolPalette.GetTabNameCount: Integer; begin Result := FTabNames.Count; end; function TJclBorRADToolPalette.GetTabNames(Index: Integer): string; begin Result := FTabNames[Index]; end; procedure TJclBorRADToolPalette.ReadTabNames; var TempList: TStringList; I: Integer; S: string; begin if Installation.ConfigData.SectionExists(Key) then begin TempList := TStringList.Create; try Installation.ConfigData.ReadSection(Key, TempList); for I := 0 to TempList.Count - 1 do begin S := TempList[I]; if Pos(PaletteHiddenTag, S) = 0 then FTabNames.Add(S); end; finally TempList.Free; end; end; end; function TJclBorRADToolPalette.TabNameExists(const TabName: string): Boolean; begin Result := FTabNames.IndexOf(TabName) <> -1; end; //=== { TJclBorRADToolRepository } =========================================== constructor TJclBorRADToolRepository.Create(AInstallation: TJclBorRADToolInstallation); begin inherited Create(AInstallation); {$IFDEF KYLIX} FFileName := AInstallation.ConfigFileName('dro'); {$ELSE} FFileName := AInstallation.BinFolderName + BorRADToolRepositoryFileName; {$ENDIF KYLIX} FPages := TStringList.Create; IniFile.ReadSection(BorRADToolRepositoryPagesSection, FPages); CloseIniFile; end; destructor TJclBorRADToolRepository.Destroy; begin FreeAndNil(FPages); FreeAndNil(FIniFile); inherited Destroy; end; procedure TJclBorRADToolRepository.AddObject(const FileName, ObjectType, PageName, ObjectName, IconFileName, Description, Author, Designer: string; const Ancestor: string); var SectionName: string; begin GetIniFile; SectionName := AnsiUpperCase(PathRemoveExtension(FileName)); FIniFile.EraseSection(FileName); FIniFile.EraseSection(SectionName); FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectType, ObjectType); FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectName, ObjectName); FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectPage, PageName); FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectIcon, IconFileName); FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectDescr, Description); FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectAuthor, Author); if Ancestor <> '' then FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectAncestor, Ancestor); if (Installation.RadToolKind = brBorlandDevStudio) or (Installation.VersionNumber >= 6) then FIniFile.WriteString(SectionName, BorRADToolRepositoryObjectDesigner, Designer); FIniFile.WriteBool(SectionName, BorRADToolRepositoryObjectNewForm, False); FIniFile.WriteBool(SectionName, BorRADToolRepositoryObjectMainForm, False); CloseIniFile; end; procedure TJclBorRADToolRepository.CloseIniFile; begin FreeAndNil(FIniFile); end; function TJclBorRADToolRepository.FindPage(const Name: string; OptionalIndex: Integer): string; var I: Integer; begin I := Pages.IndexOf(Name); if I >= 0 then Result := Pages[I] else if OptionalIndex < Pages.Count then Result := Pages[OptionalIndex] else Result := ''; end; function TJclBorRADToolRepository.GetIniFile: TIniFile; begin if not Assigned(FIniFile) then FIniFile := TIniFile.Create(FileName); Result := FIniFile; end; function TJclBorRADToolRepository.GetPages: TStrings; begin Result := FPages; end; procedure TJclBorRADToolRepository.RemoveObjects(const PartialPath, FileName, ObjectType: string); var Sections: TStringList; I: Integer; SectionName, FileNamePart, PathPart, DialogFileName: string; begin Sections := TStringList.Create; try GetIniFile; FIniFile.ReadSections(Sections); for I := 0 to Sections.Count - 1 do begin SectionName := Sections[I]; if FIniFile.ReadString(SectionName, BorRADToolRepositoryObjectType, '') = ObjectType then begin FileNamePart := PathExtractFileNameNoExt(SectionName); PathPart := StrRight(PathAddSeparator(ExtractFilePath(SectionName)), Length(PartialPath)); DialogFileName := PathExtractFileNameNoExt(FileName); if StrSame(FileNamePart, DialogFileName) and StrSame(PathPart, PartialPath) then FIniFile.EraseSection(SectionName); end; end; finally Sections.Free; end; end; //=== { TJclBorRADToolInstallation } ========================================= constructor TJclBorRADToolInstallation.Create; begin inherited Create; FConfigDataLocation := AConfigDataLocation; {$IFDEF KYLIX} FConfigData := TMemIniFile.Create(AConfigDataLocation); {$ELSE ~KYLIX} FConfigData := TRegistryIniFile.Create(AConfigDataLocation); {$ENDIF ~KYLIX} FGlobals := TStringList.Create; ReadInformation; FIdeTools := TJclBorRADToolIdeTool.Create(Self); {$IFDEF MSWINDOWS} FOpenHelp := TJclBorlandOpenHelp.Create(Self); {$ENDIF ~MSWINDOWS} FMapCreate := False; {$IFDEF MSWINDOWS} FJdbgCreate := False; FJdbgInsert := False; FMapDelete := False; if FileExists(BinFolderName + AsmExeName) then Include(FCommandLineTools, clAsm); {$ENDIF ~MSWINDOWS} if FileExists(BinFolderName + BCC32ExeName) then Include(FCommandLineTools, clBcc32); if FileExists(BinFolderName + DCC32ExeName) then Include(FCommandLineTools, clDcc32); {$IFDEF MSWINDOWS} if FileExists(BinFolderName + DCCILExeName) then Include(FCommandLineTools, clDccIL); {$ENDIF ~MSWINDOWS} if FileExists(BinFolderName + MakeExeName) then Include(FCommandLineTools, clMake); if FileExists(BinFolderName + Bpr2MakExeName) then Include(FCommandLineTools, clProj2Mak); end; destructor TJclBorRADToolInstallation.Destroy; begin FreeAndNil(FRepository); FreeAndNil(FDCC32); FreeAndNil(FBCC32); FreeAndNil(FBpr2Mak); FreeAndNil(FIdePackages); FreeAndNil(FIdeTools); {$IFDEF MSWINDOWS} FreeAndNil(FOpenHelp); {$ENDIF MSWINDOWS} FreeAndNil(FPalette); FreeAndNil(FGlobals); {$IFDEF KYLIX} FConfigData.UpdateFile; // TMemIniFile.Destroy doesn't call UpdateFile {$ENDIF KYLIX} FreeAndNil(FConfigData); inherited Destroy; end; function TJclBorRADToolInstallation.AddToDebugDCUPath(const Path: string): Boolean; var TempDebugDCUPath: TJclBorRADToolPath; begin TempDebugDCUPath := DebugDCUPath; PathListIncludeItems(TempDebugDCUPath, Path); Result := True; DebugDCUPath := TempDebugDCUPath; end; function TJclBorRADToolInstallation.AddToLibrarySearchPath(const Path: string): Boolean; var TempLibraryPath: TJclBorRADToolPath; begin TempLibraryPath := LibrarySearchPath; PathListIncludeItems(TempLibraryPath, Path); Result := True; LibrarySearchPath := TempLibraryPath; end; function TJclBorRADToolInstallation.AddToLibraryBrowsingPath(const Path: string): Boolean; var TempLibraryPath: TJclBorRADToolPath; begin TempLibraryPath := LibraryBrowsingPath; PathListIncludeItems(TempLibraryPath, Path); Result := True; LibraryBrowsingPath := TempLibraryPath; end; function TJclBorRADToolInstallation.AnyInstanceRunning: Boolean; var Processes: TStringList; I: Integer; begin Result := False; Processes := TStringList.Create; try if RunningProcessesList(Processes) then begin for I := 0 to Processes.Count - 1 do if AnsiSameText(IdeExeFileName, Processes[I]) then begin Result := True; Break; end; end; finally Processes.Free; end; end; {$IFDEF KYLIX} function TJclBorRADToolInstallation.ConfigFileName(const Extension: string): string; begin Result := ''; end; {$ENDIF KYLIX} class procedure TJclBorRADToolInstallation.ExtractPaths(const Path: TJclBorRADToolPath; List: TStrings); begin StrToStrings(Path, PathSep, List); end; function TJclBorRADToolInstallation.CompileBCBPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var SaveDir, PackagePath, MakeFileName, BinaryFileName: string; RunOnly: Boolean; begin OutputString(Format(RsCompilingPackage, [PackageName])); if not IsBCBPackage(PackageName) then raise EJclBorRADException.CreateResFmt(@RsENotABCBPackage, [PackageName]); PackagePath := PathRemoveSeparator(ExtractFilePath(PackageName)); SaveDir := GetCurrentDir; SetCurrentDir(PackagePath); try MakeFileName := StrTrimQuotes(ChangeFileExt(PackageName, '.mak')); if clProj2Mak in CommandLineTools then // let bpr2mak generate make file from .bpk begin // Kylix bpr2mak doesn't like full file names Result := Bpr2Mak.Execute(StringsToStr(Bpr2Mak.Options, ' ') + ' ' + ExtractFileName(PackageName)) end else // If make file exists (and doesn't need to be created by bpr2mak) Result := FileExists(MakeFileName); if MapCreate then Make.Options.Add('-DMAPFLAGS=-s'); GetBPKFileInfo(PackageName, RunOnly, @BinaryFileName); Result := Result and Make.Execute(Format('%s -f%s', [StringsToStr(Make.Options, ' '), StrDoubleQuote(MakeFileName)])) and ProcessMapFile(PathAddSeparator(BPLPath) + BinaryFileName); finally SetCurrentDir(SaveDir); end; if Result then OutputString(RsCompilationOk) else OutputString(RsCompilationFailed); end; function TJclBorRADToolInstallation.CompileBCBProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var SaveDir, PackagePath, MakeFileName, BinaryFileName: string; begin OutputString(Format(RsCompilingProject, [ProjectName])); if not IsBCBProject(ProjectName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiProject, [ProjectName]); PackagePath := PathRemoveSeparator(ExtractFilePath(ProjectName)); SaveDir := GetCurrentDir; SetCurrentDir(PackagePath); try MakeFileName := StrTrimQuotes(ChangeFileExt(ProjectName, '.mak')); if clProj2Mak in CommandLineTools then // let bpr2mak generate make file from .bpk // Kylix bpr2mak doesn't like full file names Result := Bpr2Mak.Execute(StringsToStr(Bpr2Mak.Options, ' ') + ' ' + ExtractFileName(ProjectName)) else // If make file exists (and doesn't need to be created by bpr2mak) Result := FileExists(MakeFileName); if MapCreate then Make.Options.Add('-DMAPFLAGS=-s'); GetBPRFileInfo(ProjectName, BinaryFileName); Result := Result and Make.Execute(Format('%s -f%s', [StringsToStr(Make.Options, ' '), StrDoubleQuote(MakeFileName)])) and ProcessMapFile(PathAddSeparator(OutputDir) + BinaryFileName); finally SetCurrentDir(SaveDir); end; if Result then OutputString(RsCompilationOk) else OutputString(RsCompilationFailed); end; function TJclBorRADToolInstallation.CompileDelphiPackage(const PackageName, BPLPath, DCPPath: string): Boolean; begin Result := CompileDelphiPackage(PackageName, BPLPath, DCPPath, ''); end; function TJclBorRADToolInstallation.CompileDelphiPackage(const PackageName, BPLPath, DCPPath, ExtraOptions: string): Boolean; var NewOptions, LibSuffix, BinaryFileName: string; RunOnly: Boolean; begin OutputString(Format(RsCompilingPackage, [PackageName])); if not IsDelphiPackage(PackageName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiPackage, [PackageName]); if MapCreate then NewOptions := ExtraOptions + ' -GD' else NewOptions := ExtraOptions; GetDPKFileInfo(PackageName, RunOnly, @LibSuffix); BinaryFileName := PathAddSeparator(BPLPath) + PathExtractFileNameNoExt(PackageName) + LibSuffix + BinaryExtensionPackage; Result := DCC32.MakePackage(PackageName, BPLPath, DCPPath, NewOptions) and ProcessMapFile(BinaryFileName); if Result then OutputString(RsCompilationOk) else OutputString(RsCompilationFailed); end; function TJclBorRADToolInstallation.CompileDelphiProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var ExtraOptions, BinaryExtension, LibSuffix, BinaryFileName: string; begin OutputString(Format(RsCompilingProject, [ProjectName])); if not IsDelphiProject(ProjectName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiProject, [ProjectName]); if MapCreate then ExtraOptions := '-GD' else ExtraOptions := ''; GetDPRFileInfo(ProjectName, BinaryExtension, @LibSuffix); BinaryFileName := PathAddSeparator(OutputDir) + PathExtractFileNameNoExt(ProjectName) + LibSuffix + BinaryExtension; Result := DCC32.MakeProject(ProjectName, OutputDir, DcpSearchPath, ExtraOptions) and ProcessMapFile(BinaryFileName); if Result then OutputString(RsCompilationOk) else OutputString(RsCompilationFailed); end; function TJclBorRADToolInstallation.CompilePackage(const PackageName, BPLPath, DCPPath: string): Boolean; var PackageExtension: string; begin PackageExtension := ExtractFileExt(PackageName); if SameText(PackageExtension,SourceExtensionBCBPackage) then Result := CompileBCBPackage(PackageName, BPLPath, DCPPath) else if SameText(PackageExtension, SourceExtensionDelphiPackage) then Result := CompileDelphiPackage(PackageName, BPLPath, DCPPath) else raise EJclBorRadException.CreateResFmt(@RsEUnknownPackageExtension, [PackageExtension]); end; function TJclBorRADToolInstallation.CompileProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var ProjectExtension: string; begin ProjectExtension := ExtractFileExt(ProjectName); if SameText(ProjectExtension,SourceExtensionBCBProject) then Result := CompileBCBProject(ProjectName, OutputDir, DcpSearchPath) else if SameText(ProjectExtension, SourceExtensionDelphiProject) then Result := CompileDelphiProject(ProjectName, OutputDir, DcpSearchPath) else raise EJclBorRadException.CreateResFmt(@RsEUnknownProjectExtension, [ProjectExtension]); end; function TJclBorRADToolInstallation.FindFolderInPath(Folder: string; List: TStrings): Integer; var I: Integer; begin Result := -1; Folder := PathRemoveSeparator(Folder); for I := 0 to List.Count - 1 do if SamePath(Folder, PathRemoveSeparator(SubstitutePath(List[I]))) then begin Result := I; Break; end; end; function TJclBorRADToolInstallation.GetBPLOutputPath: string; begin Result := SubstitutePath(ConfigData.ReadString(LibraryKeyName, LibraryBPLOutputValueName, '')); end; function TJclBorRADToolInstallation.GetBpr2Mak: TJclBpr2Mak; begin if not Assigned(FBpr2Mak) then begin if not (clProj2Mak in CommandLineTools) then raise EJclBorRadException.CreateResFmt(@RsENotFound, [Bpr2MakExeName]); FBpr2Mak := TJclBpr2Mak.Create(Self); end; Result := FBpr2Mak; end; function TJclBorRADToolInstallation.GetBCC32: TJclBCC32; begin if not Assigned(FBCC32) then begin if not (clBcc32 in CommandLineTools) then raise EJclBorRadException.CreateResFmt(@RsENotFound, [Bcc32ExeName]); FBCC32 := TJclBCC32.Create(Self); end; Result := FBCC32; end; function TJclBorRADToolInstallation.GetCommonProjectsDir: string; begin Result := DefaultProjectsDir; end; function TJclBorRADToolInstallation.GetDCC32: TJclDCC32; begin if not Assigned(FDCC32) then begin if not (clDcc32 in CommandLineTools) then raise EJclBorRadException.CreateResFmt(@RsENotFound, [Dcc32ExeName]); FDCC32 := TJclDCC32.Create(Self); end; Result := FDCC32; end; function TJclBorRADToolInstallation.GetDCPOutputPath: string; begin Result := SubstitutePath(ConfigData.ReadString(LibraryKeyName, LibraryDCPOutputValueName, '')); end; function TJclBorRADToolInstallation.GetDebugDCUPath: string; begin Result := ConfigData.ReadString(DebuggingKeyName, DebugDCUPathValueName, ''); end; function TJclBorRADToolInstallation.GetDefaultProjectsDir: string; begin {$IFDEF KYLIX} Result := GetPersonalFolder; {$ELSE ~KYLIX} Result := Globals.Values['DefaultProjectsDirectory']; if Result = '' then Result := PathAddSeparator(RootDir) + 'Projects'; {$ENDIF ~KYLIX} end; function TJclBorRADToolInstallation.GetDescription: TJclBorRADToolPath; begin Result := Format('%s %s', [Name, EditionAsText]); if InstalledUpdatePack > 0 then Result := Result + ' ' + Format(RsUpdatePackName, [InstalledUpdatePack]); end; function TJclBorRADToolInstallation.GetEditionAsText: string; begin {$IFDEF KYLIX} case Edition of deOPEN: Result := RsOpenEdition; dePRO: Result := RsProfessional; deSVR: if VersionNumber >= 2 then Result := RsEnterprise else Result := RsServerDeveloper; end; {$ELSE} Result := FEditionStr; if Length(FEditionStr) = 3 then case Edition of deSTD: if (VersionNumber >= 6) or (RadToolKind = brBorlandDevStudio) then Result := RsPersonal else Result := RsStandard; dePRO: Result := RsProfessional; deCSS: if (VersionNumber >= 5) or (RadToolKind = brBorlandDevStudio) then Result := RsEnterprise else Result := RsClientServer; deARC: Result := RsArchitect; end; {$ENDIF KYLIX} end; function TJclBorRADToolInstallation.GetEnvironmentVariables: TStrings; var EnvNames: TStringList; EnvVarKeyName: string; I: Integer; begin if FEnvironmentVariables = nil then begin FEnvironmentVariables := TStringList.Create; if ((VersionNumber >= 6) or (RadToolKind = brBorlandDevStudio)) and ConfigData.SectionExists(EnvVariablesKeyName) then begin EnvNames := TStringList.Create; try ConfigData.ReadSection(EnvVariablesKeyName, EnvNames); for I := 0 to EnvNames.Count - 1 do begin EnvVarKeyName := EnvNames[I]; FEnvironmentVariables.Values[EnvVarKeyName] := ConfigData.ReadString(EnvVariablesKeyName, EnvVarKeyName, ''); end; finally EnvNames.Free; end; end; end; Result := FEnvironmentVariables; end; function TJclBorRADToolInstallation.GetGlobals: TStrings; begin Result := FGlobals; end; function TJclBorRADToolInstallation.GetIdeExeFileName: string; {$IFDEF KYLIX} const IdeFileNames: array [brDelphi..brCppBuilder] of string = (DelphiIdeExeName, BCBIdeExeName); begin Result := FBinFolderName + IdeFileNames[RADToolKind]; end; {$ENDIF KYLIX} {$IFDEF MSWINDOWS} begin Result := Globals.Values['App']; end; {$ENDIF MSWINDOWS} function TJclBorRADToolInstallation.GetIdeExeBuildNumber: string; begin {$IFDEF KYLIX} { TODO : determine Kylix IDE build # } Result := '?'; {$ELSE} Result := VersionFixedFileInfoString(IdeExeFileName, vfFull); {$ENDIF KYLIX} end; function TJclBorRADToolInstallation.GetIdePackages: TJclBorRADToolIdePackages; begin if not Assigned(FIdePackages) then FIdePackages := TJclBorRADToolIdePackages.Create(Self); Result := FIdePackages; end; function TJclBorRADToolInstallation.GetIsTurboExplorer: Boolean; begin Result := (RadToolKind = brBorlandDevStudio) and (VersionNumber = 4) and not (clDcc32 in CommandLineTools); end; function TJclBorRADToolInstallation.GetLatestUpdatePack: Integer; begin Result := GetLatestUpdatePackForVersion(VersionNumber); end; class function TJclBorRADToolInstallation.GetLatestUpdatePackForVersion(Version: Integer): Integer; begin {$IFDEF MSWINDOWS} raise EAbstractError.CreateResFmt(@SAbstractError, ['']); // BCB doesn't support abstract keyword // dummy; BCB doesn't like abstract class functions {$ELSE MSWINDOWS} Result := 0; {$ENDIF MSWINDOWS} end; function TJclBorRADToolInstallation.GetLibrarySearchPath: TJclBorRADToolPath; begin Result := ConfigData.ReadString(LibraryKeyName, LibrarySearchPathValueName, ''); end; function TJclBorRADToolInstallation.GetMake: IJclCommandLineTool; begin if not Assigned(FMake) then begin if not (clMake in CommandLineTools) then raise EJclBorRadException.CreateResFmt(@RsENotFound, [MakeExeName]); {$IFDEF KYLIX} FMake := TJclCommandLineTool.Create(MakeExeName); {$ELSE ~KYLIX} FMake := TJclBorlandMake.Create(Self); // Set option "-l+", which enables use of long command lines. Should be // default, but there have been reports indicating that's not always the case. FMake.Options.Add('-l+'); {$ENDIF ~KYLIX} end; Result := FMake; end; function TJclBorRADToolInstallation.GetLibraryBrowsingPath: TJclBorRADToolPath; begin Result := ConfigData.ReadString(LibraryKeyName, LibraryBrowsingPathValueName, ''); end; function TJclBorRADToolInstallation.GetName: string; begin {$IFDEF KYLIX} Result := Format(RsKylixVersionName, [IDEVersionNumber, RADToolName]); {$ELSE ~KYLIX} Result := Format('%s %d', [RADToolName, IDEVersionNumber]); {$ENDIF ~KYLIX} end; function TJclBorRADToolInstallation.GetPalette: TJclBorRADToolPalette; begin if not Assigned(FPalette) then FPalette := TJclBorRADToolPalette.Create(Self); Result := FPalette; end; function TJclBorRADToolInstallation.GetRepository: TJclBorRADToolRepository; begin if not Assigned(FRepository) then FRepository := TJclBorRADToolRepository.Create(Self); Result := FRepository; end; function TJclBorRADToolInstallation.GetSupportsLibSuffix: Boolean; begin {$IFDEF KYLIX} Result := True; {$ELSE} Result := (RadToolKind = brBorlandDevStudio) or (VersionNumber >= 6); {$ENDIF KYLIX} end; function TJclBorRADToolInstallation.GetUpdateNeeded: Boolean; begin Result := InstalledUpdatePack < LatestUpdatePack; end; function TJclBorRADToolInstallation.GetValid: Boolean; begin Result := (ConfigData.FileName <> '') and (RootDir <> '') and FileExists(IdeExeFileName); end; function TJclBorRADToolInstallation.GetVclIncludeDir: string; begin Result := RootDir + RsVclIncludeDir; if not DirectoryExists(Result) then Result := ''; end; function TJclBorRADToolInstallation.InstallBCBExpert(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var BinaryFileName, Description: string; begin OutputString(Format(RsExpertInstallationStarted, [ProjectName])); GetBPRFileInfo(ProjectName, BinaryFileName, @Description); BinaryFileName := PathAddSeparator(OutputDir) + BinaryFileName; Result := CompileBCBProject(ProjectName, OutputDir, DcpSearchPath) and RegisterExpert(BinaryFileName, Description); OutputString(RsExpertInstallationFinished); end; function TJclBorRADToolInstallation.InstallBCBIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; var RunOnly: Boolean; BinaryFileName, Description: string; begin OutputString(Format(RsIdePackageInstallationStarted, [PackageName])); GetBPKFileInfo(PackageName, RunOnly, @BinaryFileName, @Description); BinaryFileName := PathAddSeparator(BPLPath) + BinaryFileName; if RunOnly then raise EJclBorRadException.CreateResFmt(@RsECannotInstallRunOnly, [PackageName]); Result := CompileBCBPackage(PackageName, BPLPath, DCPPath) and RegisterIdePackage(BinaryFileName, Description); OutputString(RsIdePackageInstallationFinished); end; function TJclBorRADToolInstallation.InstallBCBPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var RunOnly: Boolean; BinaryFileName, Description: string; begin OutputString(Format(RsPackageInstallationStarted, [PackageName])); GetBPKFileInfo(PackageName, RunOnly, @BinaryFileName, @Description); BinaryFileName := PathAddSeparator(BPLPath) + BinaryFileName; if RunOnly then raise EJclBorRadException.CreateResFmt(@RsECannotInstallRunOnly, [PackageName]); Result := CompileBCBPackage(PackageName, BPLPath, DCPPath) and RegisterPackage(BinaryFileName, Description); OutputString(RsPackageInstallationFinished); end; function TJclBorRADToolInstallation.InstallDelphiExpert(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var LibSuffix, BinaryFileName, BinaryExtension, BaseName: string; begin OutputString(Format(RsExpertInstallationStarted, [ProjectName])); BaseName := PathExtractFileNameNoExt(ProjectName); GetDPRFileInfo(ProjectName, BinaryExtension, @LibSuffix); if BinaryExtension = '' then BinaryExtension := BinaryExtensionLibrary; BinaryFileName := PathAddSeparator(OutputDir) + BaseName + LibSuffix + BinaryExtension; Result := CompileDelphiProject(ProjectName, OutputDir, DcpSearchPath) and RegisterExpert(BinaryFileName, BaseName); OutputString(RsExpertInstallationFinished); end; function TJclBorRADToolInstallation.InstallDelphiIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; var RunOnly: Boolean; LibSuffix, BPLFileName, Description: string; begin OutputString(Format(RsIdePackageInstallationStarted, [PackageName])); GetDPKFileInfo(PackageName, RunOnly, @LibSuffix, @Description); if RunOnly then raise EJclBorRadException.CreateResFmt(@RsECannotInstallRunOnly, [PackageName]); BPLFileName := PathAddSeparator(BPLPath) + PathExtractFileNameNoExt(PackageName) + LibSuffix + BinaryExtensionPackage; Result := CompileDelphiPackage(PackageName, BPLPath, DCPPath) and RegisterIdePackage(BPLFileName, Description); OutputString(RsIdePackageInstallationFinished); end; function TJclBorRADToolInstallation.InstallDelphiPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var RunOnly: Boolean; LibSuffix, BPLFileName, Description: string; begin OutputString(Format(RsPackageInstallationStarted, [PackageName])); GetDPKFileInfo(PackageName, RunOnly, @LibSuffix, @Description); if RunOnly then raise EJclBorRadException.CreateResFmt(@RsECannotInstallRunOnly, [PackageName]); BPLFileName := PathAddSeparator(BPLPath) + PathExtractFileNameNoExt(PackageName) + LibSuffix + BinaryExtensionPackage; Result := CompileDelphiPackage(PackageName, BPLPath, DCPPath) and RegisterPackage(BPLFileName, Description); OutputString(RsPackageInstallationFinished); end; function TJclBorRADToolInstallation.InstallExpert(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var ProjectExtension: string; begin ProjectExtension := ExtractFileExt(ProjectName); if SameText(ProjectExtension, SourceExtensionBCBProject) then Result := InstallBCBExpert(ProjectName, OutputDir, DcpSearchPath) else if SameText(ProjectExtension, SourceExtensionDelphiProject) then Result := InstallDelphiExpert(ProjectName, OutputDir, DcpSearchPath) else raise EJclBorRADException.CreateResFmt(@RsEUnknownProjectExtension, [ProjectExtension]); end; function TJclBorRADToolInstallation.InstallIDEPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var PackageExtension: string; begin PackageExtension := ExtractFileExt(PackageName); if SameText(PackageExtension, SourceExtensionBCBPackage) then Result := InstallBCBIdePackage(PackageName, BPLPath, DCPPath) else if SameText(PackageExtension, SourceExtensionDelphiPackage) then Result := InstallDelphiIdePackage(PackageName, BPLPath, DCPPath) else raise EJclBorRADException.CreateResFmt(@RsEUnknownIdePackageExtension, [PackageExtension]); end; function TJclBorRADToolInstallation.InstallPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var PackageExtension: string; begin PackageExtension := ExtractFileExt(PackageName); if SameText(PackageExtension, SourceExtensionBCBPackage) then Result := InstallBCBPackage(PackageName, BPLPath, DCPPath) else if SameText(PackageExtension, SourceExtensionDelphiPackage) then Result := InstallDelphiPackage(PackageName, BPLPath, DCPPath) else raise EJclBorRADException.CreateResFmt(@RsEUnknownPackageExtension, [PackageExtension]); end; {$IFDEF KEEP_DEPRECATED} function TJclBorRADToolInstallation.IsBDSPersonality: Boolean; begin {$IFDEF MSWINDOWS} Result := InheritsFrom(TJclBDSInstallation); {$ELSE} Result := False; {$ENDIF MSWINDOWS} end; {$ENDIF KEEP_DEPRECATED} function TJclBorRADToolInstallation.LibFolderName: string; begin Result := PathAddSeparator(RootDir) + PathAddSeparator('lib'); end; function TJclBorRADToolInstallation.ProcessMapFile(const BinaryFileName: string): Boolean; {$IFDEF MSWINDOWS} var MAPFileName, LinkerBugUnit: string; MAPFileSize, JclDebugDataSize: Integer; {$ENDIF MSWINDOWS} begin {$IFDEF MSWINDOWS} if JdbgCreate then begin MAPFileName := ChangeFileExt(BinaryFileName, CompilerExtensionMAP); if JdbgInsert then begin OutputString(Format(RsInsertingJdbg, [BinaryFileName])); Result := InsertDebugDataIntoExecutableFile(BinaryFileName, MAPFileName, LinkerBugUnit, MAPFileSize, JclDebugDataSize); OutputString(Format(RsJdbgInfo, [LinkerBugUnit, MAPFileSize, JclDebugDataSize])); end else begin OutputString(Format(RsCreatingJdbg, [BinaryFileName])); Result := ConvertMapFileToJdbgFile(MAPFileName); end; if Result then begin OutputString(RsJdbgInfoOk); if MapDelete then OutputFileDelete(MAPFileName); end else OutputString(RsJdbgInfoFailed); end else Result := True; {$ELSE MSWINDOWS} Result := True; {$ENDIF MSWINDOWS} end; function TJclBorRADToolInstallation.OutputFileDelete(const FileName: string): Boolean; begin OutputString(Format(RsDeletingFile, [FileName])); Result := FileDelete(FileName); if Result then OutputString(RsFileDeletionOk) else OutputString(RsFileDeletionFailed); end; procedure TJclBorRADToolInstallation.OutputString(const AText: string); begin if Assigned(FOutputCallback) then OutputCallback(AText); end; class function TJclBorRADToolInstallation.PackageSourceFileExtension: string; begin {$IFDEF MSWINDOWS} raise EAbstractError.CreateResFmt(@SAbstractError, ['']); // BCB doesn't support abstract keyword {$ELSE MSWINDOWS} Result := ''; {$ENDIF MSWINDOWS} end; class function TJclBorRADToolInstallation.ProjectSourceFileExtension: string; begin {$IFDEF MSWINDOWS} raise EAbstractError.CreateResFmt(@SAbstractError, ['']); // BCB doesn't support abstract keyword {$ELSE MSWINDOWS} Result := ''; {$ENDIF MSWINDOWS} end; class function TJclBorRADToolInstallation.RADToolKind: TJclBorRADToolKind; begin {$IFDEF MSWINDOWS} raise EAbstractError.CreateResFmt(@SAbstractError, ['']); // BCB doesn't support abstract keyword {$ELSE MSWINDOWS} Result := brDelphi; {$ENDIF MSWINDOWS} end; {class }function TJclBorRADToolInstallation.RADToolName: string; begin {$IFDEF MSWINDOWS} raise EAbstractError.CreateResFmt(@SAbstractError, ['']); // BCB doesn't support abstract keyword {$ELSE MSWINDOWS} Result := ''; {$ENDIF MSWINDOWS} end; procedure TJclBorRADToolInstallation.ReadInformation; function FormatVersionNumber(const Num: Integer): string; begin Result := ''; case RadToolKind of {$IFDEF KYLIX} brDelphi: Result := Format('kd%d', [Num]); brCppBuilder: Result := Format('kc%d', [Num]); {$ELSE ~KYLIX} brDelphi: Result := Format('d%d', [Num]); brCppBuilder: Result := Format('c%d', [Num]); {$ENDIF ~KYLIX} brBorlandDevStudio: case Num of 1 : Result := 'cs1'; else Result := Format('d%d', [Num + 6]); // BDS 2 goes to D8 end; end; end; const {$IFDEF KYLIX} BinDir = 'bin/'; {$ELSE ~KYLIX} BinDir = 'bin\'; {$ENDIF ~KYLIX} UpdateKeyName = 'Update #'; BDSUpdateKeyName = 'UpdatePackInstalled'; var KeyLen, I: Integer; Key: string; Ed: TJclBorRADToolEdition; begin Key := ConfigData.FileName; {$IFDEF KYLIX} ConfigData.ReadSectionValues(GlobalsKeyName, Globals); if Length(Key) >= 3 then begin case Key[Length(Key)-2] of '0' : FVersionNumber := 1; '5' : FVersionNumber := 2; '9' : FVersionNumber := 3; else FVersionNumber := 0; end; end; FIDEVersionNumber := VersionNumber; {$ELSE ~KYLIX} RegGetValueNamesAndValues(HKEY_LOCAL_MACHINE, Key, Globals); KeyLen := Length(Key); if (KeyLen > 3) and StrIsDigit(Key[KeyLen - 2]) and (Key[KeyLen - 1] = '.') and (Key[KeyLen] = '0') then FIDEVersionNumber := Ord(Key[KeyLen - 2]) - Ord('0') else FIDEVersionNumber := 0; // If this is Spacely, then consider the version is equal to 4 (BDS2006) // as it is a non breaking version (dcu wise) { ahuser: Delphi 2007 is a non breaking version in the case that you can use BDS 2006 compiled units in Delphi 2007. But it completely breaks the BDS 2006 installation because if BDS 2006 uses the Delphi 2007 compile DCUs the resulting executable is broken and will do strange things. So treat Delphi 2007 as version 11 what it actually is. } {if (FIDEVersionNumber = 5) and (RadToolKind = brBorlandDevStudio) then FVersionNumber := 4 else} FVersionNumber := FIDEVersionNumber; {$ENDIF ~KYLIX} FVersionNumberStr := FormatVersionNumber(VersionNumber); FIDEVersionNumberStr := FormatVersionNumber(IDEVersionNumber); FRootDir := PathRemoveSeparator(Globals.Values[RootDirValueName]); FBinFolderName := PathAddSeparator(RootDir) + BinDir; FEditionStr := Globals.Values[EditionValueName]; if FEditionStr = '' then FEditionStr := Globals.Values[VersionValueName]; { TODO : Edition detection for BDS } for Ed := Low(Ed) to High(Ed) do if StrIPos(BorRADToolEditionIDs[Ed], FEditionStr) = 1 then FEdition := Ed; if RadToolKind = brBorlandDevStudio then FInstalledUpdatePack := StrToIntDef(Globals.Values[BDSUpdateKeyName], 0) else for I := 0 to Globals.Count - 1 do begin Key := Globals.Names[I]; KeyLen := Length(UpdateKeyName); if (Pos(UpdateKeyName, Key) = 1) and (Length(Key) > KeyLen) and StrIsDigit(Key[KeyLen + 1]) then FInstalledUpdatePack := Max(FInstalledUpdatePack, Integer(Ord(Key[KeyLen + 1]) - 48)); end; end; function TJclBorRADToolInstallation.RegisterExpert(const BinaryFileName, Description: string): Boolean; var InternalDescription: string; begin OutputString(Format(RsRegisteringExpert, [BinaryFileName])); if Description = '' then InternalDescription := PathExtractFileNameNoExt(BinaryFileName) else InternalDescription := Description; Result := IdePackages.AddExpert(BinaryFileName, InternalDescription); if Result then OutputString(RsRegistrationOk) else OutputString(RsRegistrationFailed); end; function TJclBorRADToolInstallation.RegisterIDEPackage(const BinaryFileName, Description: string): Boolean; var InternalDescription: string; begin OutputString(Format(RsRegisteringIdePackage, [BinaryFileName])); if Description = '' then InternalDescription := PathExtractFileNameNoExt(BinaryFileName) else InternalDescription := Description; Result := IdePackages.AddIDEPackage(BinaryFileName, InternalDescription); if Result then OutputString(RsRegistrationOk) else OutputString(RsRegistrationFailed); end; function TJclBorRADToolInstallation.RegisterPackage(const BinaryFileName, Description: string): Boolean; var InternalDescription: string; begin OutputString(Format(RsRegisteringPackage, [BinaryFileName])); if Description = '' then InternalDescription := PathExtractFileNameNoExt(BinaryFileName) else InternalDescription := Description; Result := IdePackages.AddPackage(BinaryFileName, InternalDescription); if Result then OutputString(RsRegistrationOk) else OutputString(RsRegistrationFailed); end; function TJclBorRADToolInstallation.RemoveFromDebugDCUPath(const Path: string): Boolean; var TempDebugDCUPath: TJclBorRADToolPath; begin TempDebugDCUPath := DebugDCUPath; Result := RemoveFromPath(TempDebugDCUPath, Path); DebugDCUPath := TempDebugDCUPath; end; function TJclBorRADToolInstallation.RemoveFromLibrarySearchPath(const Path: string): Boolean; var TempLibraryPath: TJclBorRADToolPath; begin TempLibraryPath := LibrarySearchPath; Result := RemoveFromPath(TempLibraryPath, Path); LibrarySearchPath := TempLibraryPath; end; function TJclBorRADToolInstallation.RemoveFromLibraryBrowsingPath(const Path: string): Boolean; var TempLibraryPath: TJclBorRADToolPath; begin TempLibraryPath := LibraryBrowsingPath; Result := RemoveFromPath(TempLibraryPath, Path); LibraryBrowsingPath := TempLibraryPath; end; function TJclBorRADToolInstallation.RemoveFromPath(var Path: string; const ItemsToRemove: string): Boolean; var PathItems, RemoveItems: TStringList; Folder: string; I, J: Integer; begin Result := False; PathItems := nil; RemoveItems := nil; try PathItems := TStringList.Create; RemoveItems := TStringList.Create; ExtractPaths(Path, PathItems); ExtractPaths(ItemsToRemove, RemoveItems); for I := 0 to RemoveItems.Count - 1 do begin Folder := RemoveItems[I]; J := FindFolderInPath(Folder, PathItems); if J <> -1 then begin PathItems.Delete(J); Result := True; end; end; Path := StringsToStr(PathItems, PathSep, False); finally PathItems.Free; RemoveItems.Free; end; end; procedure TJclBorRADToolInstallation.SetDebugDCUPath(const Value: TJclBorRADToolPath); begin ConfigData.WriteString(DebuggingKeyName, DebugDCUPathValueName, Value); end; procedure TJclBorRADToolInstallation.SetLibrarySearchPath(const Value: TJclBorRADToolPath); begin ConfigData.WriteString(LibraryKeyName, LibrarySearchPathValueName, Value); end; procedure TJclBorRADToolInstallation.SetOutputCallback(const Value: TTextHandler); begin FOutputCallback := Value; //if clAsm in CommandLineTools then // Asm.OutputCallback := Value; if clBcc32 in CommandLineTools then Bcc32.OutputCallback := Value; if clDcc32 in CommandLineTools then Dcc32.OutputCallback := Value; //if clDccIL in CommandLineTools then // DccIL.OutputCallback := Value; if clMake in CommandLineTools then Make.OutputCallback := Value; if clProj2Mak in CommandLineTools then Bpr2Mak.OutputCallback := Value; end; procedure TJclBorRADToolInstallation.SetLibraryBrowsingPath(const Value: TJclBorRADToolPath); begin ConfigData.WriteString(LibraryKeyName, LibraryBrowsingPathValueName, Value); end; function TJclBorRADToolInstallation.SubstitutePath(const Path: string): string; var I: Integer; Name: string; begin Result := Path; if Pos('$(', Result) > 0 then with EnvironmentVariables do for I := 0 to Count - 1 do begin Name := Names[I]; Result := StringReplace(Result, Format('$(%s)', [Name]), Values[Name], [rfReplaceAll, rfIgnoreCase]); end; // remove duplicate path delimiters '\\' Result := StringReplace(Result, DirDelimiter + DirDelimiter, DirDelimiter, [rfReplaceAll]); end; {$IFDEF KEEP_DEPRECATED} function TJclBorRADToolInstallation.SupportsBCB: Boolean; begin Result := clBCC32 in CommandLineTools; end; {$ENDIF KEEP_DEPRECATED} function TJclBorRADToolInstallation.SupportsVCL: Boolean; begin {$IFDEF KYLIX} Result := False; {$ELSE ~KYLIX} Result := (RadToolKind = brBorlandDevStudio) or (VersionNumber >= 6); {$ENDIF ~KYLIX} end; function TJclBorRADToolInstallation.SupportsVisualCLX: Boolean; begin {$IFDEF KYLIX} Result := True; {$ELSE} Result := (Edition <> deSTD) and (VersionNumber in [6, 7]) and (RadToolKind <> brBorlandDevStudio); {$ENDIF KYLIX} end; function TJclBorRADToolInstallation.UninstallBCBExpert(const ProjectName, OutputDir: string): Boolean; var BinaryFileName: string; begin OutputString(Format(RsExpertUninstallationStarted, [ProjectName])); if not IsBCBProject(ProjectName) then raise EJclBorRADException.CreateResFmt(@RsENotABCBProject, [ProjectName]); GetBPRFileInfo(ProjectName, BinaryFileName); BinaryFileName := PathAddSeparator(OutputDir) + BinaryFileName; // important: remove from experts /before/ deleting; // otherwise PathGetLongPathName won't work Result := UnregisterExpert(BinaryFileName); if Result then OutputFileDelete(BinaryFileName); OutputString(RsExpertUninstallationFinished); end; function TJclBorRADToolInstallation.UninstallBCBIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; var MAPFileName, TDSFileName, BPIFileName, LIBFileName, BPLFileName: string; BinaryFileName: string; RunOnly: Boolean; begin OutputString(Format(RsIdePackageUninstallationStarted, [PackageName])); if not IsBCBPackage(PackageName) then raise EJclBorRADException.CreateResFmt(@RsENotABCBPackage, [PackageName]); GetBPKFileInfo(PackageName, RunOnly, @BinaryFileName); BPLFileName := PathAddSeparator(BPLPath) + BinaryFileName; // important: remove from IDE packages /before/ deleting; // otherwise PathGetLongPathName won't work Result := (RunOnly or UnregisterIdePackage(BPLFileName)); // Don't delete binaries if removal of design time package failed if Result then begin OutputFileDelete(BPLFileName); BPIFileName := PathAddSeparator(DCPPath) + PathExtractFileNameNoExt(PackageName) + CompilerExtensionBPI; OutputFileDelete(BPIFileName); LIBFileName := ChangeFileExt(BPIFileName, CompilerExtensionLIB); OutputFileDelete(LIBFileName); MAPFileName := ChangeFileExt(BPLFileName, CompilerExtensionMAP); OutputFileDelete(MAPFileName); TDSFileName := ChangeFileExt(BPLFileName, CompilerExtensionTDS); OutputFileDelete(TDSFileName); end; OutputString(RsIdePackageUninstallationFinished); end; function TJclBorRADToolInstallation.UninstallBCBPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var MAPFileName, TDSFileName, BPIFileName, LIBFileName, BPLFileName: string; BinaryFileName: string; RunOnly: Boolean; begin OutputString(Format(RsPackageUninstallationStarted, [PackageName])); if not IsBCBPackage(PackageName) then raise EJclBorRADException.CreateResFmt(@RsENotABCBPackage, [PackageName]); GetBPKFileInfo(PackageName, RunOnly, @BinaryFileName); BPLFileName := PathAddSeparator(BPLPath) + BinaryFileName; // important: remove from IDE packages /before/ deleting; // otherwise PathGetLongPathName won't work Result := (RunOnly or UnregisterPackage(BPLFileName)); // Don't delete binaries if removal of design time package failed if Result then begin OutputFileDelete(BPLFileName); BPIFileName := PathAddSeparator(DCPPath) + PathExtractFileNameNoExt(PackageName) + CompilerExtensionBPI; OutputFileDelete(BPIFileName); LIBFileName := ChangeFileExt(BPIFileName, CompilerExtensionLIB); OutputFileDelete(LIBFileName); MAPFileName := ChangeFileExt(BPLFileName, CompilerExtensionMAP); OutputFileDelete(MAPFileName); TDSFileName := ChangeFileExt(BPLFileName, CompilerExtensionTDS); OutputFileDelete(TDSFileName); end; OutputString(RsPackageUninstallationFinished); end; function TJclBorRADToolInstallation.UninstallDelphiExpert(const ProjectName, OutputDir: string): Boolean; var BinaryFileName: string; BaseName, LibSuffix, BinaryExtension: string; begin OutputString(Format(RsExpertUninstallationStarted, [ProjectName])); if not IsDelphiProject(ProjectName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiProject, [ProjectName]); BaseName := PathExtractFileNameNoExt(ProjectName); GetDPRFileInfo(ProjectName, BinaryExtension, @LibSuffix); if BinaryExtension = '' then BinaryExtension := BinaryExtensionLibrary; BinaryFileName := PathAddSeparator(OutputDir) + BaseName + LibSuffix + BinaryExtension; // important: remove from experts /before/ deleting; // otherwise PathGetLongPathName won't work Result := UnregisterExpert(BinaryFileName); if Result then OutputFileDelete(BinaryFileName); OutputString(RsExpertUninstallationFinished); end; function TJclBorRADToolInstallation.UninstallDelphiIdePackage(const PackageName, BPLPath, DCPPath: string): Boolean; var MAPFileName, BPLFileName, DCPFileName: string; BaseName, LibSuffix: string; RunOnly: Boolean; begin OutputString(Format(RsIdePackageUninstallationStarted, [PackageName])); if not IsDelphiPackage(PackageName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiPackage, [PackageName]); GetDPKFileInfo(PackageName, RunOnly, @LibSuffix); BaseName := PathExtractFileNameNoExt(PackageName); BPLFileName := PathAddSeparator(BPLPath) + BaseName + LibSuffix + BinaryExtensionPackage; // important: remove from IDE packages /before/ deleting; // otherwise PathGetLongPathName won't work Result := RunOnly or UnregisterIdePackage(BPLFileName); // Don't delete binaries if removal of design time package failed if Result then begin OutputFileDelete(BPLFileName); DCPFileName := PathAddSeparator(DCPPath) + BaseName + CompilerExtensionDCP; OutputFileDelete(DCPFileName); MAPFileName := ChangeFileExt(BPLFileName, CompilerExtensionMAP); OutputFileDelete(MAPFileName); end; OutputString(RsIdePackageUninstallationFinished); end; function TJclBorRADToolInstallation.UninstallDelphiPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var MAPFileName, BPLFileName, DCPFileName: string; BaseName, LibSuffix: string; RunOnly: Boolean; begin OutputString(Format(RsPackageUninstallationStarted, [PackageName])); if not IsDelphiPackage(PackageName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiPackage, [PackageName]); GetDPKFileInfo(PackageName, RunOnly, @LibSuffix); BaseName := PathExtractFileNameNoExt(PackageName); BPLFileName := PathAddSeparator(BPLPath) + BaseName + LibSuffix + BinaryExtensionPackage; // important: remove from IDE packages /before/ deleting; // otherwise PathGetLongPathName won't work Result := RunOnly or UnregisterPackage(BPLFileName); // Don't delete binaries if removal of design time package failed if Result then begin OutputFileDelete(BPLFileName); DCPFileName := PathAddSeparator(DCPPath) + BaseName + CompilerExtensionDCP; OutputFileDelete(DCPFileName); MAPFileName := ChangeFileExt(BPLFileName, CompilerExtensionMAP); OutputFileDelete(MAPFileName); end; OutputString(RsPackageUninstallationFinished); end; function TJclBorRADToolInstallation.UninstallExpert(const ProjectName, OutputDir: string): Boolean; var ProjectExtension: string; begin ProjectExtension := ExtractFileExt(ProjectName); if SameText(ProjectExtension,SourceExtensionBCBProject) then Result := UninstallBCBExpert(ProjectName, OutputDir) else if SameText(ProjectExtension, SourceExtensionDelphiProject) then Result := UninstallDelphiExpert(ProjectName, OutputDir) else raise EJclBorRadException.CreateResFmt(@RsEUnknownProjectExtension, [ProjectExtension]); end; function TJclBorRADToolInstallation.UninstallIDEPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var PackageExtension: string; begin PackageExtension := ExtractFileExt(PackageName); if SameText(PackageExtension,SourceExtensionBCBPackage) then Result := UninstallBCBIdePackage(PackageName, BPLPath, DCPPath) else if SameText(PackageExtension, SourceExtensionDelphiPackage) then Result := UninstallDelphiIdePackage(PackageName, BPLPath, DCPPath) else raise EJclBorRadException.CreateResFmt(@RsEUnknownIdePackageExtension, [PackageExtension]); end; function TJclBorRADToolInstallation.UninstallPackage(const PackageName, BPLPath, DCPPath: string): Boolean; var PackageExtension: string; begin PackageExtension := ExtractFileExt(PackageName); if SameText(PackageExtension,SourceExtensionBCBPackage) then Result := UninstallBCBPackage(PackageName, BPLPath, DCPPath) else if SameText(PackageExtension, SourceExtensionDelphiPackage) then Result := UninstallDelphiPackage(PackageName, BPLPath, DCPPath) else raise EJclBorRadException.CreateResFmt(@RsEUnknownPackageExtension, [PackageExtension]); end; function TJclBorRADToolInstallation.UnregisterExpert(const BinaryFileName: string): Boolean; begin OutputString(Format(RsUnregisteringExpert, [BinaryFileName])); Result := IdePackages.RemoveExpert(BinaryFileName); if Result then OutputString(RsUnregistrationOk) else OutputString(RsUnregistrationFailed); end; function TJclBorRADToolInstallation.UnregisterIDEPackage(const BinaryFileName: string): Boolean; begin OutputString(Format(RsUnregisteringIDEPackage, [BinaryFileName])); Result := IdePackages.RemoveIDEPackage(BinaryFileName); if Result then OutputString(RsUnregistrationOk) else OutputString(RsUnregistrationFailed); end; function TJclBorRADToolInstallation.UnregisterPackage(const BinaryFileName: string): Boolean; begin OutputString(Format(RsUnregisteringPackage, [BinaryFileName])); Result := IdePackages.RemovePackage(BinaryFileName); if Result then OutputString(RsUnregistrationOk) else OutputString(RsUnregistrationFailed); end; //=== { TJclBCBInstallation } ================================================ constructor TJclBCBInstallation.Create(const AConfigDataLocation: string); begin inherited Create(AConfigDataLocation); FPersonalities := [bpBCBuilder32]; if clDcc32 in CommandLineTools then Include(FPersonalities, bpDelphi32); end; destructor TJclBCBInstallation.Destroy; begin inherited Destroy; end; {$IFDEF KYLIX} function TJclBCBInstallation.ConfigFileName(const Extension: string): string; begin Result := Format('%s/.borland/bcb%d%s', [GetPersonalFolder, IDs[VersionNumber], Extension]); end; {$ENDIF KYLIX} function TJclBCBInstallation.GetEnvironmentVariables: TStrings; begin Result := inherited GetEnvironmentVariables; if Assigned(Result) then Result.Values['BCB'] := PathRemoveSeparator(RootDir); end; class function TJclBCBInstallation.GetLatestUpdatePackForVersion(Version: Integer): Integer; begin case Version of 5: Result := 0; 6: Result := 4; 10: Result := 0; else Result := 0; end; end; class function TJclBCBInstallation.PackageSourceFileExtension: string; begin Result := SourceExtensionBCBPackage; end; class function TJclBCBInstallation.ProjectSourceFileExtension: string; begin Result := SourceExtensionBCBProject; end; class function TJclBCBInstallation.RadToolKind: TJclBorRadToolKind; begin Result := brCppBuilder; end; function TJclBCBInstallation.RADToolName: string; begin Result := RsBCBName; end; //=== { TJclDelphiInstallation } ============================================= constructor TJclDelphiInstallation.Create(const AConfigDataLocation: string); begin inherited Create(AConfigDataLocation); FPersonalities := [bpDelphi32]; end; destructor TJclDelphiInstallation.Destroy; begin inherited Destroy; end; {$IFDEF KYLIX} function TJclDelphiInstallation.ConfigFileName(const Extension: string): string; begin Result := Format('%s/.borland/delphi%d%s', [GetPersonalFolder, IDs[VersionNumber], Extension]); end; {$ENDIF KYLIX} function TJclDelphiInstallation.GetEnvironmentVariables: TStrings; begin Result := inherited GetEnvironmentVariables; if Assigned(Result) then Result.Values['DELPHI'] := PathRemoveSeparator(RootDir); end; class function TJclDelphiInstallation.GetLatestUpdatePackForVersion(Version: Integer): Integer; begin case Version of 5: Result := 1; 6: Result := 2; 7: Result := 0; else Result := 0; end; end; function TJclDelphiInstallation.InstallPackage(const PackageName, BPLPath, DCPPath: string): Boolean; begin Result := InstallDelphiPackage(PackageName, BPLPath, DCPPath); end; class function TJclDelphiInstallation.PackageSourceFileExtension: string; begin Result := SourceExtensionDelphiPackage; end; class function TJclDelphiInstallation.ProjectSourceFileExtension: string; begin Result := SourceExtensionDelphiProject; end; class function TJclDelphiInstallation.RadToolKind: TJclBorRadToolKind; begin Result := brDelphi; end; function TJclDelphiInstallation.RADToolName: string; begin Result := RsDelphiName; end; //=== { TJclBDSInstallation } ================================================== {$IFDEF MSWINDOWS} constructor TJclBDSInstallation.Create(const AConfigDataLocation: string); const PersonalitiesSection = 'Personalities'; begin inherited Create(AConfigDataLocation); FHelp2Manager := TJclHelp2Manager.Create(Self); { TODO : .net 64 bit } if ConfigData.ReadString(PersonalitiesSection, 'C#Builder', '') <> '' then Include(FPersonalities, bpCSBuilder32); if ConfigData.ReadString(PersonalitiesSection, 'BCB', '') <> '' then Include(FPersonalities, bpBCBuilder32); if ConfigData.ReadString(PersonalitiesSection, 'Delphi.Win32', '') <> '' then Include(FPersonalities, bpDelphi32); if (ConfigData.ReadString(PersonalitiesSection, 'Delphi.NET', '') <> '') or (ConfigData.ReadString(PersonalitiesSection, 'Delphi8', '') <> '') then Include(FPersonalities, bpDelphiNet32); if clDcc32 in CommandLineTools then Include(FPersonalities, bpDelphi32); if FPersonalities = [] then raise EJclBorRadException.CreateRes(@RsENoSupportedPersonality); FDCCIL := TJclDCCIL.Create(Self); end; destructor TJclBDSInstallation.Destroy; begin FDCCIL.Free; FHelp2Manager.Free; inherited Destroy; end; function TJclBDSInstallation.AddToCppBrowsingPath(const Path: string): Boolean; var TempCppPath: TJclBorRADToolPath; begin if bpBCBuilder32 in Personalities then begin TempCppPath := CppBrowsingPath; PathListIncludeItems(TempCppPath, Path); Result := True; CppBrowsingPath := TempCppPath; end else Result := False; end; function TJclBDSInstallation.AddToCppSearchPath(const Path: string): Boolean; var TempCppPath: TJclBorRADToolPath; begin if bpBCBuilder32 in Personalities then begin TempCppPath := CppSearchPath; PathListIncludeItems(TempCppPath, Path); Result := True; CppSearchPath := TempCppPath; end else Result := False; end; function TJclBDSInstallation.AddToCppLibraryPath(const Path: string): Boolean; var TempLibraryPath: TJclBorRADToolPath; begin if (bpBCBuilder32 in Personalities) and (IDEVersionNumber >= 5) then begin TempLibraryPath := CppLibraryPath; PathListIncludeItems(TempLibraryPath, Path); Result := True; CppLibraryPath := TempLibraryPath; end else Result := False; end; function TJclBDSInstallation.CleanPackageCache(const BinaryFileName: string): Boolean; var FileName, KeyName: string; begin Result := True; if VersionNumber >= 3 then begin FileName := ExtractFileName(BinaryFileName); try OutputString(Format(RsCleaningPackageCache, [FileName])); KeyName := PathAddSeparator(ConfigDataLocation) + PackageCacheKeyName + '\' + FileName; if RegKeyExists(HKCU, KeyName) then Result := RegDeleteKeyTree(HKCU, KeyName); if Result then OutputString(RsCleaningOk) else OutputString(RsCleaningFailed); except // trap possible exceptions end; end; end; function TJclBDSInstallation.CompileDelphiDotNetProject(const ProjectName, OutputDir: string; PEFormat: TJclBorPlatform; const CLRVersion, ExtraOptions: string): Boolean; var DCCILOptions, PlatformOption, PdbOption: string; begin if VersionNumber >= 2 then // C#Builder 1 doesn't have any Delphi.net compiler begin OutputString(Format(RsCompilingProject, [ProjectName])); if not IsDelphiProject(ProjectName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiProject, [ProjectName]); PlatformOption := ''; case PEFormat of bp32bit: if VersionNumber >= 3 then PlatformOption := 'x86'; bp64bit: if VersionNumber >= 3 then PlatformOption := 'x64' else raise EJclBorRADException.CreateRes(@RsEx64PlatformNotValid); end; if PdbCreate then PdbOption := '-V' else PdbOption := ''; DCCILOptions := Format('%s --platform:%s %s', [ExtraOptions, PlatformOption, PdbOption]); Result := DCCIL.MakeProject(ProjectName, OutputDir, DCCILOptions); if Result then OutputString(RsCompilationOk) else OutputString(RsCompilationFailed); end else raise EJclBorRADException.CreateRes(@RsENoSupportedPersonality); end; function TJclBDSInstallation.CompileDelphiPackage(const PackageName, BPLPath, DCPPath, ExtraOptions: string): Boolean; var NewOptions: string; begin if DualPackageInstallation then begin if not (bpBCBuilder32 in Personalities) then raise EJclBorRadException.CreateResFmt(@RsEDualPackageNotSupported, [Name]); NewOptions := Format('%s -JL -NB"%s" -NO"%s" -N1"%s"', [ExtraOptions, DcpPath, DcpPath, VclIncludeDir]); end else NewOptions := ExtraOptions; Result := inherited CompileDelphiPackage(PackageName, BPLPath, DCPPath, NewOptions); end; function TJclBDSInstallation.CompileDelphiProject(const ProjectName, OutputDir, DcpSearchPath: string): Boolean; var ExtraOptions, BinaryExtension, LibSuffix, BinaryFileName: string; begin if VersionNumber <= 2 then begin OutputString(Format(RsCompilingProject, [ProjectName])); if not IsDelphiProject(ProjectName) then raise EJclBorRADException.CreateResFmt(@RsENotADelphiProject, [ProjectName]); if MapCreate then ExtraOptions := '-GD' else ExtraOptions := ''; GetDPRFileInfo(ProjectName, BinaryExtension, @LibSuffix); if BinaryExtension = '' then BinaryExtension := BinaryExtensionLibrary; BinaryFileName := PathAddSeparator(OutputDir) + PathExtractFileNameNoExt(ProjectName) + LibSuffix + BinaryExtension; Result := DCC32.MakeProject(ProjectName, OutputDir, DcpSearchPath, ExtraOptions) and ProcessMapFile(BinaryFileName); if Result then OutputString(RsCompilationOk) else OutputString(RsCompilationFailed); end else Result := inherited CompileDelphiProject(ProjectName, DcpSearchPath, OutputDir); end; function TJclBDSInstallation.GetBPLOutputPath: string; begin // BDS 1 (C#Builder 1) and BDS 2 (Delphi 8) don't have a valid BPL output path // set in the registry case IDEVersionNumber of 1, 2: Result := PathAddSeparator(GetDefaultProjectsDir) + 'bpl'; 3, 4: Result := inherited GetBPLOutputPath; 5: if bpBCBuilder32 in Personalities then Result := SubstitutePath(GetMsBuildEnvOption(MsBuildCBuilderBPLOutputPathNodeName)) else Result := SubstitutePath(GetMsBuildEnvOption(MsBuildWin32DLLOutputPathNodeName)); else Result := SubstitutePath(GetMsBuildEnvOption(MsBuildWin32DLLOutputPathNodeName)); end; end; function TJclBDSInstallation.GetCommonProjectsDir: string; begin if IDEVersionNumber >= 5 then begin Result := LoadResStrings(RootDir + '\Bin\coreide' + BDSVersions[IDEVersionNumber].CoreIdeVersion + '.', [BDSVersions[IDEVersionNumber].ProjectsDirResId1]); if Result = '' then Result := 'RAD Studio'; // do not localize Result := Format('%s%s%d.0', [PathAddSeparator(GetCommonDocumentsFolder), PathAddSeparator(Result), IDEVersionNumber]); end else Result := DefaultProjectsDir; end; function TJclBDSInstallation.GetCppPathsKeyName: string; begin if IDEVersionNumber >= 5 then Result := CppPathsV5UpperKeyName else Result := CppPathsKeyName; end; function TJclBDSInstallation.GetCppBrowsingPath: TJclBorRADToolPath; begin Result := ConfigData.ReadString(GetCppPathsKeyName, CppBrowsingPathValueName, ''); end; function TJclBDSInstallation.GetCppSearchPath: TJclBorRADToolPath; begin Result := ConfigData.ReadString(GetCppPathsKeyName, CppSearchPathValueName, ''); end; function TJclBDSInstallation.GetCppLibraryPath: TJclBorRADToolPath; begin Result := ConfigData.ReadString(GetCppPathsKeyName, CppLibraryPathValueName, ''); end; function TJclBDSInstallation.GetDCPOutputPath: string; begin case IDEVersionNumber of 1, 2: // hard-coded Result := PathAddSeparator(RootDir) + 'lib'; 3, 4: // use registry Result := inherited GetDCPOutputPath; //5: else // use EnvOptions.proj Result := SubstitutePath(GetMsBuildEnvOption(MsBuildWin32DCPOutputNodeName)); end; end; function TJclBDSInstallation.GetDebugDCUPath: TJclBorRADToolPath; begin if IDEVersionNumber >= 5 then // use EnvOptions.proj Result := GetMsBuildEnvOption(MsBuildWin32DebugDCUPathNodeName) else // use registry Result := ConfigData.ReadString(LibraryKeyName, BDSDebugDCUPathValueName, ''); end; function TJclBDSInstallation.GetDefaultProjectsDir: string; begin Result := LoadResStrings(RootDir + '\Bin\coreide' + BDSVersions[IDEVersionNumber].CoreIdeVersion + '.', [BDSVersions[IDEVersionNumber].ProjectsDirResId1, BDSVersions[IDEVersionNumber].ProjectsDirResId2]); if Result = '' then begin // Default values, just in case the resources are not found in the exe or localized file. if IDEVersionNumber < 5 then Result := 'Borland Studio Projects' // do not localize else Result := 'RAD Studio\Projects'; // do not localize end; Result := PathAddSeparator(GetPersonalFolder) + Result; end; function TJclBDSInstallation.GetEnvironmentVariables: TStrings; begin Result := inherited GetEnvironmentVariables; if Assigned(Result) then begin // adding default values if Result.Values[EnvVariableBDSValueName] = '' then Result.Values[EnvVariableBDSValueName] := PathRemoveSeparator(RootDir); if Result.Values[EnvVariableBDSPROJDIRValueName] = '' then Result.Values[EnvVariableBDSPROJDIRValueName] := DefaultProjectsDir; if Result.Values[EnvVariableBDSCOMDIRValueName] = '' then Result.Values[EnvVariableBDSCOMDIRValueName] := CommonProjectsDir; end; end; class function TJclBDSInstallation.GetLatestUpdatePackForVersion(Version: Integer): Integer; begin case Version of 9: Result := 1; // personal version is only update pack 1 10: Result := 1; // update 1 is out else Result := 0; end; end; function TJclBDSInstallation.GetValid: Boolean; begin Result := (inherited GetValid) and ((IDEVersionNumber < 5) or FileExists(GetMsBuildEnvOptionsFileName)); end; function TJclBDSInstallation.GetLibraryBrowsingPath: TJclBorRADToolPath; begin if IDEVersionNumber >= 5 then // use EnvOptions.proj Result := GetMsBuildEnvOption(MsBuildWin32BrowsingPathNodeName) else // use registry Result := inherited GetLibraryBrowsingPath; end; function TJclBDSInstallation.GetLibrarySearchPath: TJclBorRADToolPath; begin if IDEVersionNumber >= 5 then // use EnvOptions.proj Result := GetMsBuildEnvOption(MsBuildWin32LibraryPathNodeName) else // use registry Result := inherited GetLibrarySearchPath; end; function TJclBDSInstallation.GetMaxDelphiCLRVersion: string; begin Result := DCCIL.GetMaxCLRVersion; end; function TJclBDSInstallation.GetName: string; begin // The name comes from the IDEVersionNumber if IDEVersionNumber in [Low(BDSVersions)..High(BDSVersions)] then Result := Format('%s %s', [RadToolName, BDSVersions[IDEVersionNumber].VersionStr]) else Result := Format('%s ***%s***', [RadToolName, IDEVersionNumber]); end; function TJclBDSInstallation.GetMsBuildEnvOption(const OptionName: string): string; var EnvOptionsFile: TJclSimpleXML; PropertyGroupNode, PropertyNode: TJclSimpleXMLElem; begin Result := ''; EnvOptionsFile := TJclSimpleXML.Create; try EnvOptionsFile.LoadFromFile(GetMsBuildEnvOptionsFileName); EnvOptionsFile.Options := EnvOptionsFile.Options - [sxoAutoCreate]; PropertyGroupNode := EnvOptionsFile.Root.Items.ItemNamed[MsBuildPropertyGroupNodeName]; if Assigned(PropertyGroupNode) then begin PropertyNode := PropertyGroupNode.Items.ItemNamed[OptionName]; if Assigned(PropertyNode) then Result := PropertyNode.Value; end; finally EnvOptionsFile.Free; end; end; function TJclBDSInstallation.GetMsBuildEnvOptionsFileName: string; begin if IDEVersionNumber >= 5 then Result := Format('%sBorland\BDS\%d.0\EnvOptions.proj', [PathAddSeparator(GetAppdataFolder), IDEVersionNumber]) else raise EJclBorRADException.CreateRes(@RsMsBuildNotSupported); end; function TJclBDSInstallation.GetVclIncludeDir: string; begin if not (bpBCBuilder32 in Personalities) then raise EJclBorRadException.CreateResFmt(@RsEDualPackageNotSupported, [Name]); Result := inherited GetVclIncludeDir; end; class function TJclBDSInstallation.PackageSourceFileExtension: string; begin Result := SourceExtensionDelphiPackage; end; class function TJclBDSInstallation.ProjectSourceFileExtension: string; begin Result := SourceExtensionDelphiProject; end; class function TJclBDSInstallation.RadToolKind: TJclBorRadToolKind; begin Result := brBorlandDevStudio; end; function TJclBDSInstallation.RadToolName: string; begin // The name comes from IDEVersionNumber if IDEVersionNumber in [Low(BDSVersions)..High(BDSVersions)] then begin Result := BDSVersions[IDEVersionNumber].Name; // IDE Version 5 comes in two flavors: // - Delphi only (Spacely) // - C++ Builder only (Cogswell) // In the second case the product name is "C++ Builder" and not "Delphi" // Right now, the name of an installation of Cogswell on top of Spacely // is not yet known and a way to detect it will have to be thought of. if (IDEVersionNumber = 5) and (bpBCBuilder32 in Personalities) then Result := RsBCBName; end else Result := RsBDSName; end; function TJclBDSInstallation.RegisterPackage(const BinaryFileName, Description: string): Boolean; begin if VersionNumber >= 3 then CleanPackageCache(BinaryFileName); Result := inherited RegisterPackage(BinaryFileName, Description); end; function TJclBDSInstallation.RemoveFromCppBrowsingPath(const Path: string): Boolean; var TempCppPath: TJclBorRADToolPath; begin if bpBCBuilder32 in Personalities then begin TempCppPath := CppBrowsingPath; Result := RemoveFromPath(TempCppPath, Path); CppBrowsingPath := TempCppPath; end else Result := False; end; function TJclBDSInstallation.RemoveFromCppSearchPath(const Path: string): Boolean; var TempCppPath: TJclBorRADToolPath; begin if bpBCBuilder32 in Personalities then begin TempCppPath := CppSearchPath; Result := RemoveFromPath(TempCppPath, Path); CppSearchPath := TempCppPath; end else Result := False; end; function TJclBDSInstallation.RemoveFromCppLibraryPath(const Path: string): Boolean; var TempLibraryPath: TJclBorRADToolPath; begin if (bpBCBuilder32 in Personalities) and (IDEVersionNumber >= 5) then begin TempLibraryPath := CppLibraryPath; Result := RemoveFromPath(TempLibraryPath, Path); CppLibraryPath := TempLibraryPath; end else Result := False; end; procedure TJclBDSInstallation.SetCppBrowsingPath(const Value: TJclBorRADToolPath); begin // update registry ConfigData.WriteString(GetCppPathsKeyName, CppBrowsingPathValueName, Value); // update EnvOptions.dproj if IDEVersionNumber >= 5 then SetMsBuildEnvOption(MsBuildCBuilderBrowsingPathNodeName, Value); end; procedure TJclBDSInstallation.SetCppSearchPath(const Value: TJclBorRADToolPath); begin ConfigData.WriteString(GetCppPathsKeyName, CppSearchPathValueName, Value); end; procedure TJclBDSInstallation.SetCppLibraryPath(const Value: TJclBorRADToolPath); begin // update registry ConfigData.WriteString(GetCppPathsKeyName, CppLibraryPathValueName, Value); // update EnvOptions.dproj if IDEVersionNumber >= 5 then SetMsBuildEnvOption(MsBuildCBuilderLibraryPathNodeName, Value); end; procedure TJclBDSInstallation.SetDebugDCUPath(const Value: TJclBorRADToolPath); begin // update registry ConfigData.WriteString(LibraryKeyName, BDSDebugDCUPathValueName, Value); // update EnvOptions.dproj if IDEVersionNumber >= 5 then SetMsBuildEnvOption(MsBuildWin32DebugDCUPathNodeName, Value); end; procedure TJclBDSInstallation.SetDualPackageInstallation(const Value: Boolean); begin if Value and not (bpBCBuilder32 in Personalities) then raise EJclBorRadException.CreateResFmt(@RsEDualPackageNotSupported, [Name]); FDualPackageInstallation := Value; end; procedure TJclBDSInstallation.SetLibraryBrowsingPath(const Value: TJclBorRADToolPath); begin // update registry inherited SetLibraryBrowsingPath(Value); // update EnvOptions.dproj if IDEVersionNumber >= 5 then SetMsBuildEnvOption(MsBuildWin32BrowsingPathNodeName, Value); end; procedure TJclBDSInstallation.SetLibrarySearchPath(const Value: TJclBorRADToolPath); begin // update registry inherited SetLibrarySearchPath(Value); // update EnvOptions.dproj if IDEVersionNumber >= 5 then SetMsBuildEnvOption(MsBuildWin32LibraryPathNodeName, Value); end; procedure TJclBDSInstallation.SetMsBuildEnvOption(const OptionName, Value: string); var EnvOptionsFileName: string; EnvOptionsFile: TJclSimpleXML; PropertyGroupNode, PropertyNode: TJclSimpleXMLElem; begin EnvOptionsFile := TJclSimpleXML.Create; try EnvOptionsFileName := GetMsBuildEnvOptionsFileName; EnvOptionsFile.LoadFromFile(EnvOptionsFileName); EnvOptionsFile.Options := EnvOptionsFile.Options + [sxoAutoCreate]; PropertyGroupNode := EnvOptionsFile.Root.Items.ItemNamed[MsBuildPropertyGroupNodeName]; PropertyNode := PropertyGroupNode.Items.ItemNamed[OptionName]; PropertyNode.Value := Value; EnvOptionsFile.SaveToFile(EnvOptionsFileName); finally EnvOptionsFile.Free; end; end; procedure TJclBDSInstallation.SetOutputCallback(const Value: TTextHandler); begin inherited SetOutputCallback(Value); if clDccIL in CommandLineTools then DCCIL.OutputCallback := Value; end; function TJclBDSInstallation.UnregisterPackage(const BinaryFileName: string): Boolean; begin if IDEVersionNumber >= 3 then CleanPackageCache(BinaryFileName); Result := inherited UnregisterPackage(BinaryFileName); end; {$ENDIF MSWINDOWS} //=== { TJclBorRADToolInstallations } ======================================== constructor TJclBorRADToolInstallations.Create; begin FList := TObjectList.Create; ReadInstallations; end; destructor TJclBorRADToolInstallations.Destroy; begin FreeAndNil(FList); inherited Destroy; end; function TJclBorRADToolInstallations.AnyInstanceRunning: Boolean; var I: Integer; begin Result := False; for I := 0 to Count - 1 do if Installations[I].AnyInstanceRunning then begin Result := True; Break; end; end; function TJclBorRADToolInstallations.AnyUpdatePackNeeded(var Text: string): Boolean; var I: Integer; begin Result := False; for I := 0 to Count - 1 do if Installations[I].UpdateNeeded then begin Result := True; Text := Format(RsNeedUpdate, [Installations[I].LatestUpdatePack, Installations[I].Name]); Break; end; end; function TJclBorRADToolInstallations.GetCount: Integer; begin Result := FList.Count; end; function TJclBorRADToolInstallations.GetBCBInstallationFromVersion(VersionNumber: Integer): TJclBorRADToolInstallation; var I: Integer; begin Result := nil; for I := 0 to Count - 1 do case Installations[I].RadToolKind of brCppBuilder: if Installations[I].IDEVersionNumber = VersionNumber then begin Result := Installations[I]; Break; end; brBorlandDevStudio: if (VersionNumber >= 10) and (Installations[I].IDEVersionNumber = (VersionNumber - 6)) then begin Result := Installations[I]; Break; end; end; end; function TJclBorRADToolInstallations.GetDelphiInstallationFromVersion(VersionNumber: Integer): TJclBorRADToolInstallation; var I: Integer; begin Result := nil; for I := 0 to Count - 1 do case Installations[I].RadToolKind of brDelphi: if Installations[I].IDEVersionNumber = VersionNumber then begin Result := Installations[I]; Break; end; brBorlandDevStudio: if (VersionNumber >= 8) and (Installations[I].IDEVersionNumber = (VersionNumber - 6)) then begin Result := Installations[I]; Break; end; end; end; function TJclBorRADToolInstallations.GetInstallations(Index: Integer): TJclBorRADToolInstallation; begin Result := TJclBorRADToolInstallation(FList[Index]); end; function TJclBorRADToolInstallations.GetBCBVersionInstalled(VersionNumber: Integer): Boolean; begin Result := BCBInstallationFromVersion[VersionNumber] <> nil; end; function TJclBorRADToolInstallations.GetBDSInstallationFromVersion(VersionNumber: Integer): TJclBorRADToolInstallation; var I: Integer; begin Result := nil; for I := 0 to Count - 1 do if (Installations[I].IDEVersionNumber = VersionNumber) and (Installations[I].RadToolKind = brBorlandDevStudio) then begin Result := Installations[I]; Break; end; end; function TJclBorRADToolInstallations.GetBDSVersionInstalled(VersionNumber: Integer): Boolean; begin Result := BDSInstallationFromVersion[VersionNumber] <> nil; end; function TJclBorRADToolInstallations.GetDelphiVersionInstalled(VersionNumber: Integer): Boolean; begin Result := DelphiInstallationFromVersion[VersionNumber] <> nil; end; function TJclBorRADToolInstallations.Iterate(TraverseMethod: TTraverseMethod): Boolean; var I: Integer; begin Result := True; for I := 0 to Count - 1 do Result := Result and TraverseMethod(Installations[I]); end; procedure TJclBorRADToolInstallations.ReadInstallations; {$IFDEF KYLIX} var I: Integer; procedure CheckForInstallation(RADToolKind: TJclBorRADToolKind; VersionNumber: Integer); const RcBaseFileNames: array [brDelphi..brCppBuilder] of string = ('delphi', 'bcb'); var Item: TJclBorRADToolInstallation; RcFileName: string; begin RcFileName := Format('%s/.borland/%s%drc', [GetPersonalFolder, RcBaseFileNames[RADToolKind], IDs[VersionNumber]]); if FileExists(RcFileName) then begin if RADToolKind = brCppBuilder then Item := TJclBCBInstallation.Create(RcFileName) else Item := TJclDelphiInstallation.Create(RcFileName); Item.FVersionNumber := VersionNumber; Item.FIDEVersionNumber := VersionNumber; FList.Add(Item); end; end; begin FList.Clear; for I := Low(TKylixVersion) to High(TKylixVersion) do CheckForInstallation(brDelphi, I); CheckForInstallation(brCppBuilder, 3); // Kylix 3 only end; {$ELSE ~KYLIX} var VersionNumbers: TStringList; function EnumVersions(const KeyName: string; const Personalities: array of string; CreateClass: TJclBorRADToolInstallationClass): Boolean; var I, J: Integer; VersionKeyName, PersonalitiesKeyName: string; PersonalitiesList: TStrings; Installation: TJclBorRADToolInstallation; begin Result := False; if RegKeyExists(HKEY_LOCAL_MACHINE, KeyName) and RegGetKeyNames(HKEY_LOCAL_MACHINE, KeyName, VersionNumbers) then for I := 0 to VersionNumbers.Count - 1 do if StrIsSubSet(VersionNumbers[I], ['.', '0'..'9']) then begin VersionKeyName := KeyName + DirDelimiter + VersionNumbers[I]; if RegKeyExists(HKEY_LOCAL_MACHINE, VersionKeyName) then begin if Length(Personalities) = 0 then begin try Installation := CreateClass.Create(VersionKeyName); if Installation.Valid then FList.Add(Installation); finally Result := True; end; end else begin PersonalitiesList := TStringList.Create; try PersonalitiesKeyName := VersionKeyName + '\Personalities'; if RegKeyExists(HKEY_LOCAL_MACHINE, PersonalitiesKeyName) then RegGetValueNames(HKEY_LOCAL_MACHINE, PersonalitiesKeyName, PersonalitiesList); for J := Low(Personalities) to High(Personalities) do if PersonalitiesList.IndexOf(Personalities[J]) >= 0 then begin try Installation := CreateClass.Create(VersionKeyName); if Installation.Valid then FList.Add(Installation) else Installation.Free; finally Result := True; end; Break; end; finally PersonalitiesList.Free; end; end; end; end; end; begin FList.Clear; VersionNumbers := TStringList.Create; try EnumVersions(DelphiKeyName, [], TJclDelphiInstallation); EnumVersions(BCBKeyName, [], TJclBCBInstallation); EnumVersions(BDSKeyName, ['Delphi.Win32', 'BCB', 'Delphi8', 'C#Builder'], TJclBDSInstallation); finally VersionNumbers.Free; end; end; {$ENDIF ~KYLIX} //=== { TJclCommandLineTool } ================================================ constructor TJclCommandLineTool.Create(const AExeName: string); begin inherited Create; FOptions := TStringList.Create; FExeName := AExeName; end; destructor TJclCommandLineTool.Destroy; begin FreeAndNil(FOptions); inherited Destroy; end; procedure TJclCommandLineTool.AddPathOption(const Option, Path: string); var S: string; begin S := PathRemoveSeparator(Path); {$IFDEF MSWINDOWS} S := LowerCase(S); // file names are case insensitive {$ENDIF MSWINDOWS} S := Format('-%s"%s"', [Option, S]); // avoid duplicate entries (note that search is case sensitive) if GetOptions.IndexOf(S) = -1 then GetOptions.Add(S); end; function TJclCommandLineTool.Execute(const CommandLine: string): Boolean; begin if Assigned(FOutputCallback) then Result := JclSysUtils.Execute(Format('"%s" %s', [ExeName, CommandLine]), FOutputCallback) = 0 else Result := JclSysUtils.Execute(Format('"%s" %s', [ExeName, CommandLine]), FOutput) = 0; end; function TJclCommandLineTool.GetExeName: string; begin Result := FExeName; end; function TJclCommandLineTool.GetOptions: TStrings; begin Result := FOptions; end; function TJclCommandLineTool.GetOutput: string; begin Result := FOutput; end; function TJclCommandLineTool.GetOutputCallback: TTextHandler; begin Result := FOutputCallback; end; procedure TJclCommandLineTool.SetOutputCallback(const CallbackMethod: TTextHandler); begin FOutputCallback := CallbackMethod; end; {$IFDEF UNITVERSIONING} initialization RegisterUnitVersion(HInstance, UnitVersioning); finalization UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} end.