; This is an Inno Setup Script for the OANDA ; Application ; ; This is the dBASE Plus 2019 version. ; ; There is a special CODE section at the end which updates ; the Windows Registry specifically for the purpose of ; the BDE. The reason? The RUN section is executed after ; the REGISTRY section, and therefore overwrites whatever ; is put there. The code at the end runs at the "PostInstall" ; step of this script, and updates the Windows Registry ; keys as defined ... ; ; Update in December, 2023 to use custom constants ... ; Custom Constants: #DEFINE AppName "Ordinary and Armorial" #DEFINE AppVersion "16.02" ; Name of Installer Program (include version #): #DEFINE InstallProgram "OandA16_02" #DEFINE AppYear "2024" ; for Windows app menu and icon placed on desktop: #DEFINE WindowsIconName "OandA" ; misc: #DEFINE AppWebAddress "http://www.goldenstag.net/OandA" #DEFINE BusinessName "Golden Stag Productions" ; folder level 1: #DEFINE PathBusiness "GSP" ; folder level 2: #DEFINE PathAppName "OandA" [Setup] ; ----------------------------------------------------- ; Name of program to run OutputBaseFilename={#InstallProgram} ; ----------------------------------------------------- ; Output directory -- where the install program ; gets created (this will be "under" the source, i.e, ; C:\Vesper\InstallImage): OutputDir=InstallImage ; ----------------------------------------------------- ; Source folder for files (where is your application?): SourceDir=F:\OandA_2019 ; ----------------------------------------------------- ; Application folder, C:\Program Files (x86)\GSP\OandA ; ; From the dBASE OLH: ; Install executable code under the Program Files folder tree and NOT attempt ; to modify or create any new files under this folder tree while running the program. ; (Standard users generally have only read and execute permissions to files under ; this folder tree. In order to modify or create files under this folder tree, a program ; would need either administrator permissions or custom permissions. However, standard ; users would not be able to run such a program). DefaultDirName={pf}\GSP\OandA ; Don't allow user to select paths ... DisableDirPage=yes ; ----------------------------------------------------- ; Name of group that is created DefaultGroupName={#AppName} ; Don't allow user to change group name (default is no): DisableProgramGroupPage=yes ; ----------------------------------------------------- ; Items involved in install program display, or in the ; install program's properties (right-click it ...): AppCopyright=Copyright ©{#AppYear} - {#BusinessName} AppID={#AppName} AppPublisher={#BusinessName} AppPublisherURL={#AppWebAddress} AppUpdatesURL={#AppWebAddress} AppSupportURL={#AppWebAddress} ; Application Name -- as it will appear in Setup program (upper left corner) AppName={#AppName} ; Version -- required AppVersion={#AppVersion} AppVerName={#AppName}, ver. {#AppVersion} ; ----------------------------------------------------- ; Version Information -- Version: VersionInfoVersion={#AppVersion} ; If you need something different from the above ... ; uses AppPublisher if nothing is set: VersionInfoCompany={#BusinessName} ; uses AppCopyright if nothing is set: VersionInfoCopyright=Copyright ©{#AppYear} - {#BusinessName} ; uses AppName if nothing is set: VersionInfoProductName={#AppName} ; uses AppName if nothing is set: VersionInfoDescription="SCA Ordinary and Armorial program, converts UNIX text file to relational database, and has an interface to search and return results in a variety of ways." ; uses VersionInfoVersion if not set: VersionInfoProductVersion={#AppVersion} ; uses VersionInfoVersion or AppVersion if not set: VersionInfoTextVersion={#AppVersion} ; ----------------------------------------------------- ; Setup wizard SetupIconFile="InstallerImages\StagHead.ico" WizardImageBackColor=clGreen WizardImageFile="InstallerImages\SmallStag.bmp" WizardImageStretch=no ; ----------------------------------------------------- ; Uninstallable ...? Uninstallable=yes ; ----------------------------------------------------- ; Ask about reboot of Windows when done ... -- default is "yes" RestartIfNeededByRun=no ; -- Text Files -- ; License file - the license here was copied from ; http://www.gnu.org/licenses/#GPL - it is a generic ; General Public License ... LicenseFile=GNU License\license.txt [Dirs] ; ----------------------------------------------------- ; ProgramData, C:\ProgramData\GSP\OandA ; From the dBASE OLH: ; Place shared configuration and non-updateable data files under the ProgramData folder ; tree - but NOT attempt to modify or create any new files under this folder tree while ; running the program. ; ; (By default, standard users have readonly access to this folder tree). ; However, this should allow the temporary files used by the BDE ; to be created in the same folder the executable is run from. ; It's a conundrum, because you shouldn't be modifying files in this ; folder from your app, but the BDE does what it wants to do ... Name: "{commonappdata}\{#PathBusiness}\{#PathAppName}"; Permissions: everyone-modify; ; ----------------------------------------------------- ; Configuration files? I am not sure my app needs to do this. ; From the dBASE OLH: ; Place master copies of files needed by each user under the ProgramData folder tree ; (to be copied to each user's private folder tree). ; ----------------------------------------------------- ; Data is being placed in two locations. ; The "EmptyTables" folder is a special location that is read-only, under: ; C:\ProgramData\GSP\OandA Name: "{commonappdata}\{#PathBusiness}\{#PathAppName}\EmptyTables"; Permissions: everyone-readexec; ; This is where the data is supposed to be placed, this is editable: ; C:\Users\username\AppData\Local ... Name: "{localappdata}\{#PathBusiness}\{#PathAppName}\Data"; Permissions: everyone-modify; ; ----------------------------------------------------- ; Private data files (I don't believe my application needs these): ; From the dBASE OLH: ; Setup a private folder tree under the Users folder tree for each user when a user first ; runs the program so that each user can modify their private files however they wish ; without interferring with other users. ; Private files would include: ; * ini file or other configuration files with user specific settings ; ** By definition of the UAC Compliant app, a copy of the .INI file ; is copied (or created) here, under a folder with the same name ; as the application's folder structure. ; * private copies of files each user may need which they can modify without affecting other users ; * any user specific data files that an application may be designed to create or modify ; * any temporary files created while running the application ; ; The OLH says: ; The first time a user runs the application, the dBASE runtime will create a private ; user folder for the user's application data and, if not disabled, and if one does not ; already exist, it will create (or copy in) a private user copy of the ; application's .ini file. ; ; For this app, see the INI section below ... ; ----------------------------------------------------- ; Doc files ... this will create the appropriate place -- (C:\ProgramData\Oanda\GSP\Docs) ; as these are read-only, this should be good enough ...: Name: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Docs"; Permissions: everyone-modify; ; ; ----------------------------------------------------- ; Icons folder -- using DEO, we can store the icons here: Name: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Icons"; Permissions: everyone-modify; ; ; ----------------------------------------------------- ; Images folder -- using DEO, we can store images here: Name: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Images"; Permissions: everyone-modify; ; ----------------------------------------------------- ; Where the dBASE Plus Runtime Engine will go: "C:\Program Files (x86)" if on ; 64-bit versions of Windows, or on 32-bit versions, "C:\Program Files"): Name: "{pf}\dBASE\Plus\Runtime"; Permissions: everyone-readexec; Flags: uninsneveruninstall; ; ----------------------------------------------------- ; Where the BDE will go: Name: "{cf}\Borland\BDE"; Permissions: everyone-full; Flags: uninsneveruninstall; [Files] ; ----------------------------------------------------- ; The application itself, to the application folder: Source: "OANDA.EXE"; DestDir: "{app}"; Flags: ignoreversion; ; ----------------------------------------------------- ; Don't forget your .INI file -- this should go in the {app} folder: Source: "Full Set of Empty Tables\OANDA.ini"; DestDir: "{app}"; Flags: ignoreversion; ; ----------------------------------------------------- ; Help files (HTML and screen shots) Source: "Docs\*.*"; DestDir: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Docs"; Flags: ignoreversion; ; ----------------------------------------------------- ; Image files (Stag Head, splash ...) Source: "Images\*.*"; DestDir: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Images"; Flags: ignoreversion; ; ----------------------------------------------------- ; Icon files (.ico, .png (for pushbuttons) ...) Source: "Icons\*.*"; DestDir: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Icons"; Flags: ignoreversion; ; ----------------------------------------------------- ; Misc. files: ; (Nothing here -- removed "gradient") ; Golden Stag Resource File (button images) -- replaced with folder of images ;Source: "GSPRES32.DLL"; DestDir: "{app}"; Flags: ignoreversion; ; ----------------------------------------------------- ; Readme file, note the flags parameter Source: "README.TXT"; DestDir: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Docs"; Flags: isreadme ignoreversion; ; ----------------------------------------------------- ; Tables, indexes and .dbts to the application\tables folder: ; There should be two sets of the tables according to the standard ; UAC information, one of them (the editable copy) in the ; path under the users' name: ; C:\Users\username\AppData\Local\GSP\OandA\Data Source: "Full Set of Empty Tables\*.*"; DestDir: "{localappdata}\{#PathBusiness}\{#PathAppName}\Data"; Flags: ignoreversion; ; Tables, indexes and .dbts to the application\EmptyTables folder: ; This is so we can restore the tables, a couple of them have actual data that ; might be an issue if we have a data corruption problem, these are important ... ; Having a complete set of these won't make the installer much bigger, and ; will provide a safety net in case of problems somewhere down the road. ; This will place them in the ProgramData folder structure, which is ; by definition read/execute, but not editable: ; C:\ProgramData\GSP\OandA\EmptyTables Source: "Full Set of Empty Tables\*.*"; DestDir: "{commonappdata}\{#PathBusiness}\{#PathAppName}\EmptyTables"; Flags: ignoreversion; ; ----------------------------------------------------- ; dBASE Runtime Installer Source: "C:\Program Files (x86)\dBASE\dBASE2019\Runtime\dBASE_2019_RuntimeAndBDE_b2618_ALL.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall ; ----------------------------------------------------- ; Manifest file for runtime: Source: "C:\Program Files (x86)\dBASE\dBASE2019\Runtime\plusrun.exe.manifest"; DestDir: "{pf}\dBASE\Plus\Runtime" ; Manifest file for BDE: Source: "C:\Program Files (x86)\dBASE\dBASE2019\Runtime\bdeadmin.exe.manifest"; DestDir: "{cf}\Borland\BDE" ; Manifest file for OandA: Source: "Manifest\OandA.exe.manifest"; DestDir: "{app}"; Flags: ignoreversion [INI] ; ----------------------------------------------------- ; Update the .ini file for the User BDE Alias: Filename: {app}\OandA.ini; Section: "UserBDEAliases"; Filename: {app}\OandA.ini; Section: "UserBDEAliases"; Key: "0"; String: "OandA"; Filename: {app}\OandA.ini; Section: "OandA"; Filename: {app}\OandA.ini; Section: "OandA"; Key: "Driver"; String: "DBASE"; Filename: {app}\OandA.ini; Section: "OandA"; Key: "Options"; String: "PATH: ""{localappdata}\{#PathBusiness}\{#PathAppName}\Data"""; ; Empty Tables database (used to copy to live data if tables corrupted): Filename: {app}\OandA.ini; Section: "UserBDEAliases"; Key: "1"; String: "OandAET"; Filename: {app}\OandA.ini; Section: "OandAET"; Filename: {app}\OandA.ini; Section: "OandAET"; Key: "Driver"; String: "DBASE"; Filename: {app}\OandA.ini; Section: "OandAET"; Key: "Options"; String: "PATH: ""{commonappdata}\{#PathBusiness}\{#PathAppName}\EmptyTables"""; ; ; Location of DOCS files: Filename: {app}\OandA.ini; Section: "Docs"; Filename: {app}\OandA.ini; Section: "Docs"; Key: "Path"; String: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Docs"; ; DEO Paths for images and icons: Filename: {app}\OandA.ini; Section: "ObjectPath"; Filename: {app}\OandA.ini; Section: "ObjectPath"; Key: "objPath0"; String: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Icons"; Filename: {app}\OandA.ini; Section: "ObjectPath"; Key: "objPath1"; String: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Images"; ; According to Marty Kay, this is how the .INI file is handled: ; You can place the default .INI file, either in {app} (the folder containing your application ; .exe) or in an application folder under \ProgramData (ex: C:\ProgramData\YourApp\YourApp.ini) ; (This folder is what should end up in _app.exename) ; ; When the application .exe is started, the runtime engine will check for the .ini under ; C:\Users\\AppData\Local\YourApp. ; (_app.currentUserPath) ; ; If this user folder does not exist, the runtime engine will create it. ; ; If no .ini is found here, the runtime will look under C:\ProgramData\YourApp. ; (_app.allUsersPath) If an .ini is found here, it will be copied to the user's private ; folder tree. ; ; If no .ini is found under ProgramData, the runtime will look in the folder containing the ; application .exe. If found, the .ini will be copied into the user's private folder tree. ; ; If no .ini is found in the above locations, a new one will be created. ; ; Keep in mind that if, at startup, the user's private folder tree already exists and ; contains an .ini file, that .ini file will be used and no further search will occur. ; ; For .exe built with INI ROAM settings in BUILD command: ; Instead of checking for an application .ini file in ; _app.currentUserPath, the _app.roamingUsersPath will be used instead. [Run] ; dBASE 2019 -- parameter of /S is the "silent" install Filename: {tmp}\dBASE_2019_RuntimeAndBDE_b2618_ALL; Parameters: "/S"; Flags: runascurrentuser waituntilterminated runhidden; Description: "dBASE Runtime and BDE"; StatusMsg: "Installing dBASE Runtime and BDE..."; WorkingDir: {tmp}; ; ----------------------------------------------------------------------------------------------------- [Registry] ; Also from the dBASE OLH: ; Install any user specific registry keys for the application under ; HKEY_CURRENT_USER\Software node ; ; NOTE: According to the Inno Setup website, the [Registry] section runs BEFORE anything in the [Run] ; section, this is not a top-down program. This is why the BDE settings in the registry are in ; a set of code in the [Code] section below, with a check to make sure we are in "PostInstall" (after ; the rest of the install is complete). ; ; Also (for the application itself): ; If the application creates or modifies any registry settings while running, it must be ; updated to ensure that these settings are located under the HKEY_CURRENT_USER node in ; the registry. ; ; For this application, where is the main tables folder? Setting this so that we can use it ; in the installer for the data, which gets updated more often than the software (approximately ; every month). By setting it here, when we run the separate installer for the data, we check ; for this path, and know where to install the updated data files. It's a neat little trick ... ; HKEY_CURRENT_USER\Software\GSP\Oanda\DataFolder Root: HKCU; Subkey: "Software\{#PathBusiness}\{#PathAppName}\"; ValueType: string; ValueName: "DataFolder"; ValueData: "{localappdata}\{#PathBusiness}\{#PathAppName}\Data" ; ------------------------------------------------------------------------------ ; Note: to handle the Borland Database Engine Registry issues, see CODE section ; below. ; ------------------------------------------------------------------------------ [Icons] ; Application icon Name: "{group}\{#WindowsIconName}"; Filename: "{app}\OandA.exe"; WorkingDir: "{app}" ; Readme: Name: "{group}\Readme.txt"; Filename: "{commonappdata}\{#PathBusiness}\{#PathAppName}\Docs\readme.txt"; WorkingDir: "{app}"; ; Desktop icons: Name: "{userdesktop}\{#WindowsIconName}"; Filename: "{app}\OandA.exe"; IconFilename: "{app}\OandA.exe"; WorkingDir: "{app}"; Comment: "Ordinary and Armorial Program"; ; ----------------------------------------------------- ; End of main OandA.iss Inno Setup script ; ----------------------------------------------------- ;------------------------------------------------------------ ; The code section uses a form of Pascal and must be the last part of the Script. ; For this install we are going to deal with with Registry settings for the BDE in a "PostInstall" ; setting ... This is because this has to run *after* the BDE is installed -- which may set ; defaults that are not what we want, or need. [Code] procedure CurStepChanged(CurStep: TSetupStep); begin if CurStep = ssPostInstall then begin // At the suggestion of Jonny Kwekkeboom, check to see if registry keys exist -- if they don't user may have // cancelled the BDE/Runtime installation, which means the application won't run. However, if they did // that, then in theory they should know it. In 2024 -- Noted that on my Windows 11 machine, I always ended up // getting the error, and realized that this was using HKLM, rather than HKEY_LOCAL_MACHINE in the // call to RegKeyExists() below. Oddly this wasn't causing an error on my desktop computer. if RegKeyExists( HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT' ) then begin // BDE Registry settings, these are all based on the appendices of The dBASE Book, which are taken from // recommendations from a variety of developers. // // NOTE: in a 64 bit version of Windows, these will appear, if you use the REGEDIT program, // under HKEY_CURRENT_USER\SOFTWARE\WOW6432Node because you're installing 32-bit software on // a 64-bit computer, and this is how Microsoft chose to handle it -- you do NOT need to // do anything for this, and you do not need to change anything: // The following are under the System\INIT structure: // LOCAL SHARE: TRUE RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'LOCAL SHARE', 'TRUE'); // MAXFILEHANDLES: 4096 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'MAXFILEHANDLES', '4096'); // MAXBUFSIZE: 16384 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'MAXBUFSIZE', '16384'); // MINBUFSIZE: 4096 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'MINBUFSIZE', '4096'); // MEMSIZE: 205 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'MEMSIZE', '205'); // SHAREDMEMSIZE: 16384 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'SHAREDMEMSIZE', '16384'); // LOW MEMORY USAGE LIMIT: 32 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'LOW MEMORY USAGE LIMIT', '32'); // LANGDRIVER: DBWINWE0 (or 'WEuropean ANSI') RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\System\INIT', 'LANGDRIVER', 'DBWINWE0'); // The following are under the DRIVERS\DBASE\INIT structure: // LANGDRIVER: DBWINWE0 (or 'WEuropean ANSI') RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\INIT', 'LANGDRIVER', 'DBWINWE0'); // The following are under the DRIVERS\DBASE\TABLE CREATE structure: // LEVEL: 7 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\TABLE CREATE', 'LEVEL', '7'); // MDX BLOCK SIZE: 1024 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\TABLE CREATE', 'MDX BLOCK SIZE', '1024'); // MEMO FILE BLOCK SIZE: 1024 RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Borland\Database Engine\Settings\DRIVERS\DBASE\TABLE CREATE', 'MEMO FILE BLOCK SIZE', '1024'); end else // there is a problem, Houston ... you will want to use appropriate wording for your application, language, etc.: MsgBox( 'Database Engine Not Installed -- This application will not function properly without it. Please re-install and complete the BDE/Runtime installation.', mbError, MB_OK ); // no 'end' statement necessary after "end else" end; // CurStep = ssPostInstall then end; // end of procedure // ---------------------------------------------------------- // ------------------ End of CODE section ------------------ // ----------------------------------------------------------