8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 18:43:02 +01:00

Add fbit - the firebird binary test_installer. This is for internal testing of the firebird binary install kits.

This commit is contained in:
Paul Reeves 2021-01-19 15:30:00 +01:00
parent 00d6f8f0e1
commit 3f8e21d679
4 changed files with 1153 additions and 0 deletions

View File

@ -0,0 +1,152 @@
Setup Command Line Parameters
(Taken from InnoSetup Help v. 6.1.2 Deember 2020)
The Setup program accepts optional command line parameters. These can be useful to system administrators, and to other programs calling the Setup program.
/HELP, /?
Shows a summary of this information. Ignored if the UseSetupLdr [Setup] section directive was set to no.
/SP-
Disables the This will install... Do you wish to continue? prompt at the beginning of Setup. Of course, this will have no effect if the DisableStartupPrompt [Setup] section directive was set to yes.
/SILENT, /VERYSILENT
Instructs Setup to be silent or very silent. When Setup is silent the wizard and the background window are not displayed but the installation progress window is. When a setup is very silent this installation progress window is not displayed. Everything else is normal so for example error messages during installation are displayed and the startup prompt is (if you haven't disabled it with DisableStartupPrompt or the '/SP-' command line option explained above).
If a restart is necessary and the '/NORESTART' command isn't used (see below) and Setup is silent, it will display a Reboot now? message box. If it's very silent it will reboot without asking.
/SUPPRESSMSGBOXES
Instructs Setup to suppress message boxes. Only has an effect when combined with '/SILENT' or '/VERYSILENT'.
The default response in situations where there's a choice is:
•Yes in a 'Keep newer file?' situation.
•No in a 'File exists, confirm overwrite.' situation.
•Abort in Abort/Retry situations.
•Cancel in Retry/Cancel situations.
•Yes (=continue) in a DiskSpaceWarning/DirExists/DirDoesntExist/NoUninstallWarning/ExitSetupMessage/ConfirmUninstall situation.
•Yes (=restart) in a FinishedRestartMessage/UninstalledAndNeedsRestart situation.
•The recommended choice in a PrivilegesRequiredOverridesAllowed=dialog situation.
5 message boxes are not suppressible:
•The About Setup message box.
•The Exit Setup? message box.
•The FileNotInDir2 message box displayed when Setup requires a new disk to be inserted and the disk was not found.
•Any (error) message box displayed before Setup (or Uninstall) could read the command line parameters.
•Any task dialog or message box displayed by [Code] support functions TaskDialogMsgBox and MsgBox.
/ALLUSERS
Instructs Setup to install in administrative install mode. Only has an effect when the [Setup] section directive PrivilegesRequiredOverridesAllowed allows the commandline override.
/CURRENTUSER
Instructs Setup to install in non administrative install mode. Only has an effect when the [Setup] section directive PrivilegesRequiredOverridesAllowed allows the commandline override.
/LOG
Causes Setup to create a log file in the user's TEMP directory detailing file installation and [Run] actions taken during the installation process. This can be a helpful debugging aid. For example, if you suspect a file isn't being replaced when you believe it should be (or vice versa), the log file will tell you if the file was really skipped, and why.
The log file is created with a unique name based on the current date. (It will not overwrite or append to existing files.)
The information contained in the log file is technical in nature and therefore not intended to be understandable by end users. Nor is it designed to be machine-parsable; the format of the file is subject to change without notice.
/LOG="filename"
Same as /LOG, except it allows you to specify a fixed path/filename to use for the log file. If a file with the specified name already exists it will be overwritten. If the file cannot be created, Setup will abort with an error message.
/NOCANCEL
Prevents the user from cancelling during the installation process, by disabling the Cancel button and ignoring clicks on the close button. Useful along with '/SILENT' or '/VERYSILENT'.
/NORESTART
Prevents Setup from restarting the system following a successful installation, or after a Preparing to Install failure that requests a restart. Typically used along with /SILENT or /VERYSILENT.
/RESTARTEXITCODE=exit code
Specifies a custom exit code that Setup is to return when the system needs to be restarted following a successful installation. (By default, 0 is returned in this case.) Typically used along with /NORESTART. See also: Setup Exit Codes
/CLOSEAPPLICATIONS
Instructs Setup to close applications using files that need to be updated by Setup if possible.
/NOCLOSEAPPLICATIONS
Prevents Setup from closing applications using files that need to be updated by Setup. If /CLOSEAPPLICATIONS was also used, this command line parameter is ignored.
/FORCECLOSEAPPLICATIONS
Instructs Setup to force close when closing applications.
/NOFORCECLOSEAPPLICATIONS
Prevents Setup from force closing when closing applications. If /FORCECLOSEAPPLICATIONS was also used, this command line parameter is ignored.
/LOGCLOSEAPPLICATIONS
Instructs Setup to create extra logging when closing applications for debugging purposes.
/RESTARTAPPLICATIONS
Instructs Setup to restart applications if possible.
/NORESTARTAPPLICATIONS
Prevents Setup from restarting applications. If /RESTARTAPPLICATIONS was also used, this command line parameter is ignored.
/LOADINF="filename"
Instructs Setup to load the settings from the specified file after having checked the command line. This file can be prepared using the '/SAVEINF=' command as explained below.
Don't forget to use quotes if the filename contains spaces.
/SAVEINF="filename"
Instructs Setup to save installation settings to the specified file.
Don't forget to use quotes if the filename contains spaces.
/LANG=language
Specifies the language to use. language specifies the internal name of the language as specified in a [Languages] section entry.
When a valid /LANG parameter is used, the Select Language dialog will be suppressed.
/DIR="x:\dirname"
Overrides the default directory name displayed on the Select Destination Location wizard page. A fully qualified pathname must be specified. May include an "expand:" prefix which instructs Setup to expand any constants in the name. For example: '/DIR=expand:{autopf}\My Program'.
/GROUP="folder name"
Overrides the default folder name displayed on the Select Start Menu Folder wizard page. May include an "expand:" prefix, see '/DIR='. If the [Setup] section directive DisableProgramGroupPage was set to yes, this command line parameter is ignored.
/NOICONS
Instructs Setup to initially check the Don't create a Start Menu folder check box on the Select Start Menu Folder wizard page.
/TYPE=type name
Overrides the default setup type.
If the specified type exists and isn't a custom type, then any /COMPONENTS parameter will be ignored.
/COMPONENTS="comma separated list of component names"
Overrides the default component settings. Using this command line parameter causes Setup to automatically select a custom type. If no custom type is defined, this parameter is ignored.
Only the specified components will be selected; the rest will be deselected.
If a component name is prefixed with a "*" character, any child components will be selected as well (except for those that include the dontinheritcheck flag). If a component name is prefixed with a "!" character, the component will be deselected.
This parameter does not change the state of components that include the fixed flag.
Example:
Deselect all components, then select the "help" and "plugins" components:
/COMPONENTS="help,plugins" Example:
Deselect all components, then select a parent component and all of its children with the exception of one:
/COMPONENTS="*parent,!parent\child"
/TASKS="comma separated list of task names"
Specifies a list of tasks that should be initially selected.
Only the specified tasks will be selected; the rest will be deselected. Use the /MERGETASKS parameter instead if you want to keep the default set of tasks and only select/deselect some of them.
If a task name is prefixed with a "*" character, any child tasks will be selected as well (except for those that include the dontinheritcheck flag). If a task name is prefixed with a "!" character, the task will be deselected.
Example:
Deselect all tasks, then select the "desktopicon" and "fileassoc" tasks:
/TASKS="desktopicon,fileassoc" Example:
Deselect all tasks, then select a parent task and all of its children with the exception of one:
/TASKS="*parent,!parent\child"
/MERGETASKS="comma separated list of task names"
Like the /TASKS parameter, except the specified tasks will be merged with the set of tasks that would have otherwise been selected by default.
If UsePreviousTasks is set to yes, the specified tasks will be selected/deselected after any previous tasks are restored.
Example:
Keep the default set of selected tasks, but additionally select the "desktopicon" and "fileassoc" tasks:
/MERGETASKS="desktopicon,fileassoc" Example:
Keep the default set of selected tasks, but deselect the "desktopicon" task:
/MERGETASKS="!desktopicon"
/PASSWORD=password
Specifies the password to use. If the [Setup] section directive Password was not set, this command line parameter is ignored.
When an invalid password is specified, this command line parameter is also ignored.

View File

@ -0,0 +1,164 @@
## Firebird Binary Installer Test Harness - FBIT
### Quick Start
* DO NOT run this script in a production environment.
* Using a snapshotted VM is recommended for initial use.
* Open a command prompt and execute
``fbit.bat HELP``
to see what parameters you can pass. Or jump to [examples](#Examples)
### Introduction
The executable Firebird Binary Installer is designed to be as simple as possible, allowing users of any level to more or less click through to have a working install. Options are kept as simple as possible so that the installation will work, no matter which options have been chosen. In addition the installer can be run from a batch script. This enables developers to embed it within their own deployment application.
Over the years bug reports have been made in the tracker but these are often untestable.
There have also been feature requests made and most have not made it into the installer. This is for two reasons:
* More options can be visually confusing during an interactive install, and certainly make a click through install more difficult for users as they are forced to make decision even though they may know nothing about Firebird.
* More options means more installation configurations are possible and there has not been a reliable method of testing these combinations
Currently this test harness consists of a single script. It is hoped that using it will make it easier to add new features as well as verify and reliably reproduce problems so that they can be fixed. Other scripts are planned for addition at a later date.
#### Intended Audience
This test harness is for anyone who wishes to integrate a scripted install of Firebird into their own installer or deployment program.
It is also intended to help developers to create reproduceable bug reports if they do experience installation problems.
##### WARNING
> This script is not intended for use in a production environment.
> IT IS DELIBERATELY DESTRUCTIVE AS IT WILL DELETE THE INSTALLED VERSION OF FIREBIRD ON COMPLETION.
However it only installs and uninstalls Firebird using the features of the installer. It does not do anything that can not already be done with the installer itself.
It should also be noted that this script is not intended to be an example of best practice as far as creating a scripted install of Firebird is concerned. The script is way too complicated for that as it needs to support as many possible installation configurations as possible.
#### Assumptions
The script has only been tested on Windows 10 20H2 as an Administrator with UAC turned off.
The script can be run multiple times with different configurations. It is intended that the results of different install configurations can be compared with a tool such as BeyondCompare.
It is preferable that Firebird is not already installed. However, it doesn't matter as testing with an existing version of Firebird installed is itself a valid test of the installer. Such a test should fail and the results can be used for future analysis.
The script is designed to:
- execute a combination of installation options,
- make a copy of the new install
- save the install log and the install configuration into the copy of the install
- immediately uninstall the package
- save the uninstall log with the copy of the installation
- Generate some visual indications of the outcome of the installation and uninstallation
It is **NOT** designed for testing Firebird after the install has completed. However, if you wish to do so be sure to pass NOUNINSTALL otherwise the script will uninstall Firebird immediately.
#### System Requirements
* The test script is designed to run on Windows systems that are currently supported by Microsoft. It should run on earlier versions too but they may lack features that have been introduced into newer releases of Windows.
* A version of grep needs to be on the path. Other posix tools _may_ be required at a later date.
* A Firebird Binary installer package is required. Any version of Firebird _should_ work but testing has only been done with Firebird 4.
There are no particular installation requirements. The script is intended to be run at command prompt.
#### Configuration
There are some hard coded variables near the beginning of the script. These need to be changed to suit your setup. In particular, FBINST_EXEC must point to the Firebird Binary Installer you wish to test. See the section :SET_GLOBAL_ENV in the script.
#### Examples
Here is a typical configuration to run the regular interactive installer:
``fbit.bat``
This will produce the same installation, but entirely scripted:
``fbit.bat SCRIPTED``
Uninstallation is automatic and by default will leave files such as firebird.conf in place. There is a 'clean' option to test complete removal of a Firebird install:
``fbit.bat SCRIPTED CLEAN``
This sort of command will override the defaults to install Firebird SuperClassic as an application with no automatic start:
``fbit.bat SCRIPTED SUPERCLASSIC APPTASK NOAUTOSTART``
All install runs are archived into %USERPROFILE%\fbit-tests with a unique name. You can add your own test identifier by passing TESTNAME name
After a full firebird build from the same console prompt where run_all.bat was run this command will test the freshly built package:
``..\install\arch-specific\win32\test_installer\fbit.bat SCRIPTED CLEAN TESTNAME SmokeTestAfterBuild``
#### Functionality Not Yet Implemented
* A detailed explanation of InnoSetup error codes will be added.
* Some more verifications will be added
- test that server is running
- SYSDBA can connect to employee db locally and via localhost
#### Known issues and problems
1/ The current focus of FBIT is to test Firebird specific features of the installer. It is not intended as a generic test tool for all InnoSetup based installers. Many scriptable options of InnoSetup based installers have not been implemented and perhaps may never be implemented.
MERGE_TASKS is currently not possible as it requires use of the ! exclamation mark to unset a task. However FBIT uses Delayed Variable Expansion which strips all instances of '!' during assignment.
The /HELP option is not implemented and probably never will.
/CURRENTUSER and /ALLUSERS may be implemented at a later date.
The various options around RESTART, CLOSE APPS, RESTARTCLOSEDAPPS have not been implemented mainly because the installer does not use them. They may never be implemented in the test harness.
/LOADINF hasn't been implemented but could be.
/DIR, /TYPE, /TASKS, /COMPONENTS, /LOG and /SAVEINF are implemented internally in FBIT. It doesn't make sense to expose them.
/GROUP and /NOICONS could be implemented but currently are not.
/LANG= probably will be implemented in fbit but is not currently available.
A full list of the standard InnoSetup commandline params as of December 2020 is available in a text file accompanying this package.
2/ Parameter passing is not 100% reliable.
3/ Uninstall error codes from InnoSetup are not reliable.
4/ Cancelling an interactive uninstall is not detected. Verification of the cancelled uninstall will subsequently detect errors that are not in fact errors.
5/ Installation type always becomes CustomInstall.
6/ It is not possible to choose the installation language used by scripted installs.
7/ Running an interactive install with this script is not well tested.
#### When things go wrong
What could possibly go wrong?
### Future Enhancements
Possible features that will be added to the harness are:
* Diagnostic report of an existing Firebird installation along with details of O/S and H/W
* A test suite that runs through all known/reasonable combination of options
* A script to uninstall MS runtimes that have been deployed by the installer.
* A means to scrub the registry of all references to previous Firebird installs.

View File

@ -0,0 +1,88 @@
Firebird Binary Installer Test Harness HELP (Designed with TABS=4 and console width=120)
fbit {PARAM [...]]
Parameters may be passed in any order except for one special case:
fbit CLEAN
will clean up from previous broken installs. CLEAN must the first parameter
and subsequent parameters are ignored. Note: - It will run silently.
By default fbit installs Firebird according to the parameters passed and then
immediately uninstalls it. A copy of the install is made, along with the install and uninstall logs.
FBIT Specific Parameters
========================
Param Name Value Passed Comment
---------- ------------ -------
HELP - Displays this screen
DRYRUN - Show what will be done. No changes are made
NOARCHIVE - Disables copying of install dir to %USERPROFILE%\fbit
Logs and inf files are always saved.
NOUNINSTALL - Disable automatic uninstall for this test run
SCRIPTED - Sets VERYSILENT, SP and NOMSG
TESTNAME NameOfTestRun Optional. No spaces allowed. Used for storing test run details.
The following parameters are set by default. They are unset automatically when a conflicting parameter is passed.
Default Param Value Unset by
------------- ------------- ----------
INTERACTIVE True SCRIPTED
INSTALLTYPE ServerInstall CLIENT or DEVINST
SERVICE_TASK True APPTASK
SUPERSERVER True CLASSICSERVER or SUPERCLASSIC
Firebird Installer specific Parameters
======================================
Param Name Value passed Action when set
---------- ------------------------- ---------------
COPYGDSLIB CopyFbClientAsGds32Task Copy fbclient to <SYS> and rename to gds32
FORCE FORCE Force installation
NOAUTOSTART NULL Does not set AutoStartTask
NOCOPYFBLIB CopyFbClientToSysTask Does not copy fbclient to <SYS>
PASSWORD /SYSDBAPASSWORD=%ISC_PASSWORD% Changes SYSDBA password from masterkey
See :SET_GLOBAL_ENV
Installation Tasks
==================
Param Name Value passed Comment
------------- ------------ ---------------
APPTASK UseApplicationTask Will not install as a service
CLASSICSERVER UseClassicServerTask Will configure classic server
SUPERCLASSIC UseSuperClassicTask Will configure super classic
Installation Types
==================
Param Name Value passed Comment
------------ ------------ -------
CLIENT ClientInstall Minimal working client install
DEVINST DeveloperInstall Everything but the server.
Uninstallation
==============
Param Name Value passed Comment
-------------- ------------ -------
CLEAN CLEAN Completely remove the firebird install
Reset list of shared dll's in the registry
Generic InnoSetup parameters
============================
Param Name Value passed Comment
---------- ------------ -------
NOMSG SUPPRESSMSGBOXES Suppress message boxes
NOCANCEL NOCANCEL Prevents user cancelling install
SILENT SILENT
SP SP- Disables the This will install... prompt
VERYSILENT VERYSILENT
-------------------------- End of Fbit Help Screen ----------------------------------------

View File

@ -0,0 +1,749 @@
@setlocal enabledelayedexpansion
:: DEBUG is intended for setting echo on globally. Each sub-routine tests
:: for DEBUG and if set VERBOSE is set. As each sub-routine exits VERBOSE
:: unset.
:: Uncomment 'call SET_VERBOSE' where needed to turn on VERBOSE
:: NOTE - DEBUG and VERBOSE still need some work around the use of the @ prefix.
@set DEBUG=
@if not defined DEBUG @echo off
:: Use this to check UAC status
:: - 0x1 means UAC is on and user will be asked for permission
:: - 0x0 means that UAC is off and install/uninstall will run without asking for permission
:: - User with Admin rights is still recommended.
::reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA | grep REG | cut -d" " -f 13
:: NOTE - This script is not intended as an example of best practice for a
:: scripted install of Firebird. It is designed to test almost all possible
:: scriptable combinations and is thus far more complicated than a typical
:: install script need be. However, it can be used for testing. Note that chosen
:: settings :: used for each test run are saved into an .inf file, along with a
:: log of the install run.
@goto :MAIN %*
@goto :EOF
::=======================================================
:SET_GLOBAL_ENV
@call :SET_VERBOSE_IF_DEBUG_ON
@if defined DEBUG @echo Entering %0
:: FBINST_EXEC must point to the package we want to test...
if not defined FBINST_EXEC (
rem - if we have just built firebird we can test the install immediately
if defined FBBUILD_FILE_ID (
if defined FBBUILD_FILENAME_SUFFIX (
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.exe
) else (
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%.exe
)
)
) else (
rem Set the actual path and filename here - or set it in the environment before running fbit.
@set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-4.0.0.2311_0_x64_RC1.exe
)
:: This should be set dynamically, perhaps. But for now it is hard-coded.
@set FIREBIRD_BASE_VER=Firebird_4_0
:: It is possible that successive installs into the same directory may
:: generate different uninstallers but for now we hard code the default.
@set UNINSTALLEXE=unins000.exe
:: The log dir should probably be under %TEMP% (or something like that)
:: In any case we try to create it if it doesn't exist
@set FBINSTALLLOGDIR=%USERPROFILE%\fbit-tests\logs
:: We use this dir to store copies of each install for future comparison
:: Perhaps this should be under the User's dir?
@set FBINSTALLCOPYDIR=%USERPROFILE%\fbit-tests\install_archive
:: This is just the default root directory for all versions of firebird
@set FIREBIRDROOTDIR="%ProgramFiles%\Firebird"
:: This is the default click through install dir.
:: It is created by the installer if it does not exist.
@set FIREBIRD=%FIREBIRDROOTDIR%\%FIREBIRD_BASE_VER%
:: Set this to 1 if you want to see the generated final command in the screen
:: output. Innosetup stores it automatically in the log file so this is not
:: necessary in normal use. Displaying it also makes the screen output harder
:: to read.
@set SHOW_FINAL_CMD=
:: change as reqd, or comment out if ISC_PASSWORD is already set in your env
@set ISC_PASSWORD="secret"
@set TAB= &
@if not defined DRYRUN (
if not exist %FBINSTALLLOGDIR% @mkdir %FBINSTALLLOGDIR% >nul 2>nul
if not exist %FBINSTALLCOPYDIR% @mkdir %FBINSTALLCOPYDIR% >nul 2>nul
)
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::====SET_GLOBAL_ENV============================================
::=======================================================
:GET_OPTS
@call :SET_VERBOSE_IF_DEBUG_ON
if defined DEBUG @echo Entering %0
:: Automatically parse the commandline and place all valid options into ENV VARS
:: Courtesy of this link:
:: https://stackoverflow.com/questions/3973824/windows-bat-file-optional-argument-parsing
::@setlocal enabledelayedexpansion
:: NOTE 1: These variable names are case insensitive - we can pass CLEAN or
:: clean, for example.
:: NOTE 2: Variables with defaults are impossible to undefine via passing
:: parameters. They must be undefined in code.
:: NOTE 3: Most variables are flags. If a flag has a default it will take the
:: value of the next flag on the command line. For example
:: flag: flagwithdefault:1
:: and this order of params:
:: flagwithdefault flag
:: will end up as
:: flagwithdefault=flag
:: Basically all this means that these variables should not be passed to runtime:
:: INTERACTIVE INSTALL INSTALLTYPE SERVER SERVICE_TASK SUPERSERVER
set "options=APPTASK: CLASSICSERVER: CLEAN: CLIENT: CMD_PARAMS: COMPONENTS: COPYGDSLIB: DEVINST: DRYRUN: FINALCMD: FULL_CMD: FORCE: HELP: INTERACTIVE:1 INSTALL:1 INSTALLTYPE:ServerInstall NOARCHIVE: NOAUTOSTART: NOCANCEL: NOCOPYFBLIB: NOMSG: NOUNINSTALL: PASSWORD: RUN_TIMESTAMP: SCRIPTED: SERVER:1 SILENT: SP: SERVICE_TASK:1 SUPERCLASSIC: SUPERSERVER:1 TASK_LIST:UseSuperServerTask TESTNAME:"" UNINSTALL: VERYSILENT: XRESULT:0"
if defined VERBOSE @echo on
for %%O in (%options%) do (
for /f "tokens=1,* delims=:" %%A in ("%%O") do (
set "%%A=%%~B"
)
)
if defined VERBOSE (
call :PRINT_VARS
if NOT defined DEBUG pause
)
:loop
if not "%~1"=="" (
set "test=!options:*%~1:=! "
if "!test!"=="!options! " (
echo Error: Invalid option %~1
) else if "!test:~0,1!"==" " (
set "%~1=1"
) else (
set "%~1=%~2"
shift
)
@if defined VERBOSE (
@set %1
if NOT defined DEBUG pause
)
shift
goto :loop
)
if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::=======================================================
::=======================================================
:SET_PARAMS
@call :SET_VERBOSE_IF_DEBUG_ON
@if defined DEBUG @echo Entering %0
::@call :SET_VERBOSE
:: Current possible install options (FB4 RC1)
:: [Types] - ServerInstall DeveloperInstall ClientInstall CustomInstall
:: [Components] - ServerComponent DevAdminComponent ClientComponent
:: [Tasks] - UseClassicServerTask UseSuperClassicTask UseSuperClassicTask\UseGuardianTask ^
:: UseSuperServerTask UseSuperServerTask\UseGuardianTask UseApplicationTask UseServiceTask ^
:: AutoStartTask CopyFbClientToSysTask CopyFbClientAsGds32Task
:: Defaults are
:: SetupType=serverinstall
:: Components=servercomponent,devadmincomponent,clientcomponent
:: Tasks=usesuperservertask,useservicetask,autostarttask,copyfbclienttosystask
:: InnoSetup can use MERGETASKS to add non-exclusive tasks to the default list.
:: For example:
:: MERGETASKS="UseSuperServerTask\UseGuardianTask,CopyFbClientAsGds32Task"
:: UNFORTUNATELY we can't negate tasks with ! if delayed variable expansion is
:: used so this option is not very useful to us.
::
:: Instead we use TASKS to entirely redefine the task list. For example:
:: TASKS="UseClassicServerTask,UseApplicationTask,CopyFbClientAsGds32Task"
:: There are other things we could test, maybe one day. See the installer help
:: dialogue or innosetup help for setup commandline params.
:: FBIT uses SCRIPTED to automatically set /SP- /VERYSILENT /SUPPRESSMSGBOXES
:: INTERACTIVE and SCRIPTED are incompatible. INTERACTIVE is default but the
:: variable is never tested.
@if defined SCRIPTED (
set VERYSILENT=VERYSILENT
set SP=SP-
set NOMSG=SUPPRESSMSGBOXES
set INTERACTIVE=
)
@if defined UNINSTALL (
set INSTALL=
@if defined CLEAN ( set CMD_PARAMS=!CMD_PARAMS! /CLEAN )
rem We now have everything we need for uninstall so jump to the end
goto :SET_CMD_PARAMS
)
:: Fix up any incompatible assignments
@if defined CLASSICSERVER ( set SUPERSERVER=& set SUPERCLASSIC=)
@if defined SUPERCLASSIC ( set SUPERSERVER=& set CLASSICSERVER=)
:: Theoretically this next line is redundant
@if defined SUPERSERVER ( set SUPERCLASSIC=& set CLASSICSERVER=)
@if defined CLIENT ( set INSTALLTYPE=ClientInstall & set DEVINST=& set SERVER=)
@if defined DEVINST (set INSTALLTYPE=DeveloperInstall & set SERVER=)
:: Theoretically this next line is redundant
@if defined SERVER (set INSTALLTYPE=ServerInstall )
:: Now build our task list
@if defined CLASSICSERVER ( set TASK_LIST=UseClassicServerTask)
@if defined SUPERCLASSIC ( set TASK_LIST=UseSuperClassicTask)
:: Theoretically this next line is redundant
@if defined SUPERSERVER ( set TASK_LIST=UseSuperServerTask)
@if defined APPTASK (
set TASK_LIST=!TASK_LIST!,UseApplicationTask
) else (
set TASK_LIST=!TASK_LIST!,UseServiceTask
)
@if NOT defined NOAUTOSTART (
set TASK_LIST=!TASK_LIST!,AutoStartTask
set INSTALLTYPE=CustomInstall
)
if NOT defined NOCOPYFBLIB (
set TASK_LIST=!TASK_LIST!,CopyFbClientToSysTask
set INSTALLTYPE=CustomInstall
)
@if defined COPYGDSLIB (
set TASK_LIST=!TASK_LIST!,CopyFbClientAsGds32Task
set INSTALLTYPE=CustomInstall
)
:SET_CMD_PARAMS
:: set up the CMD_PARAMS variable we will use
@if defined FORCE (set CMD_PARAMS=!CMD_PARAMS! /FORCE )
@if defined NOCANCEL (set CMD_PARAMS=!CMD_PARAMS! /NOCANCEL )
:: Setting PASSWORD is only relevant for a server install
@if defined PASSWORD (
@if defined SERVER (
set SYSDBAPASSWORD=%ISC_PASSWORD%
set CMD_PARAMS=!CMD_PARAMS! /SYSDBAPASSWORD=%SYSDBAPASSWORD%
set INSTALLTYPE=CustomInstall
)
)
if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES
if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT
if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP-
if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT
:: Setting CustomInstall clears the default COMPONENTS list so we
:: must define it manually
@if /I %INSTALLTYPE% == "CustomInstall" (
@if defined CLIENT ( set COMPONENTS=ClientComponent)
@if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent)
) else (
set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent
)
if defined INSTALL (
set FULL_CMD=/TYPE=!INSTALLTYPE! /TASKS="!TASK_LIST!" /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
) else (
set FULL_CMD=!CMD_PARAMS!
)
@if defined VERBOSE (
@call :PRINT_VARS
if NOT defined DEBUG pause
)
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===SET_PARAMS==========================================
::=======================================================
:PRINT_VARS
:: if a variable is not defined we don't print it, except for critical
:: variables such as FINALCMD that MUST be defined.
@echo Variables set during script execution are:
@set ADIRNAME
@set APPTASK 2>nul
@set CLASSICSERVER 2>nul
@set CLEAN 2>nul
@set CLIENT 2>nul
@set CMD_PARAMS 2>nul
@set COMPONENTS 2>nul
@set COPYGDSLIB 2>nul
@set DEVINST 2>nul
@set DRYRUN 2>nul
@set FBINST_EXEC
@set FINALCMD 2>nul
@set FULL_CMD
@set FORCE 2>nul
@set INTERACTIVE 2>nul
@set INSTALL 2>nul
@set MERGE_TASKS 2>nul
@set NOARCHIVE= 2>nul
@set NOAUTOSTART 2>nul
@set NOCANCEL 2>nul
@set NOCOPYFBLIB 2>nul
@set NOMSG 2>nul
@set NOUNINSTALL 2>nul
@set PASSWORD 2>nul
@set RUN_TIMESTAMP 2>nul
@set SCRIPTED 2>nul
@set SERVICE_TASK 2>nul
@set SERVER 2>nul
@set SERVICE_TASK 2>nul
@set SILENT 2>nul
@set SP 2>nul
@set SUPERCLASSIC 2>nul
@set SUPERSERVER 2>nul
@set TASK_LIST 2>nul
@set TESTNAME 2>nul
@set UNINSTALL 2>nul
@set VERYSILENT 2>nul
@echo.
@goto :EOF
::=======================================================
::=======================================================
:RUN_INSTALLER
@echo.
@echo.
@call :SET_VERBOSE_IF_DEBUG_ON
if defined DEBUG @echo Entering %0 %*
::@call :CHECK_ENV || (@echo Check the values in SET_ENV & goto :EOF )
@call :CHECK_ENV
::@call :RESET_INSTALL_ENV
@call :GET_OPTS %*
@call :SET_PARAMS %*
::@call :SET_VERBOSE
@if defined VERBOSE @echo on
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
@if defined VERBOSE ( if NOT defined DEBUG pause )
@call :TIMESTAMP
@set RUN_TIMESTAMP=%TIMESTAMP%
@set INSTALL_TIMESTAMP=%TIMESTAMP%
set FINALCMD=%FBINST_EXEC% %FULL_CMD% /DIR=%FIREBIRD% /LOG=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%.log /SAVEINF=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%-saved.inf
if defined DRYRUN (
@echo DRYRUN - Not executing call %FINALCMD%
) else (
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
call %FINALCMD%
@if errorlevel 1 (
rem @echo Calling %FBINST_EXEC% failed with %ERRORLEVEL%
set _err=%ERRORLEVEL%
call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD%
set /A XRESULT+=1
) else (
@echo Calling %FBINST_EXEC%......................SUCCESS!
)
@echo.
@echo Now checking system state...
if not defined NOCOPYFBLIB (
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll good bad err_is_fail
) else (
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
)
if not defined COPYGDSLIB (
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
) else (
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll good bad err_is_fail
)
@echo.
@call :COPY_INSTALL
@echo.
)
@echo.
@echo %0 completed with %XRESULT% errors
@set XRESULT=0
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@echo.
@echo.
@goto :EOF
::===RUN_INSTALLER=================================
::=========================================================
:RUN_UNINSTALLER
@echo.
@echo.
@call :SET_VERBOSE_IF_DEBUG_ON
::@call :SET_VERBOSE
@if defined DEBUG @echo Entering %0 %*
::@call :RESET_INSTALL_ENV
@call :GET_OPTS %* UNINSTALL
@call :SET_PARAMS
::@call :SET_VERBOSE
@if defined VERBOSE @echo on
@if defined VERBOSE call :PRINT_VARS
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
@if defined NOUNINSTALL (
@echo NOUNINSTALL was passed. Exiting %0.
@goto :EOF
)
@call :TIMESTAMP
@set RUN_TIMESTAMP=%TIMESTAMP%
@set FINALCMD=%FIREBIRD%\%UNINSTALLEXE% %FULL_CMD% /log=%FBINSTALLLOGDIR%\uninstall%RUN_TIMESTAMP%.log
@if defined VERBOSE ( if NOT defined DEBUG (pause) )
@if defined DRYRUN (
echo DRYRUN - Not executing call %FINALCMD%
if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@echo.
@echo.
goto :EOF
)
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
call %FINALCMD% 2>nul
if errorlevel 1 (
set _err=%ERRORLEVEL%
) else (
set _err=0
)
if %_err% GEQ 1 (
set _err=%ERRORLEVEL%
call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD%
set /A XRESULT+=1
) else (
echo Calling %FIREBIRD%\%UNINSTALLEXE% ................SUCCESS!
)
rem We need to give time to the uninstaller to clean up
rem If the install is interactive we need to close the final msg box first
rem If the install is scripted we need to pause a few seconds.
rem Change as required for your system.
if INTERACTIVE equ 1 (
echo Close the uninstaller dialog now!!!
timeout /t 10
) else (
timeout /t 3
)
echo.
echo Now checking system state...
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
if defined CLEAN (
call :CHECKSHAREDDLLS
call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail
)
echo.
call :COPY_INSTALL
echo.
)
echo.
echo %0 completed with %XRESULT% errors
set XRESULT=0
if defined DEBUG @echo Leaving %0
call :UNSET_VERBOSE
@echo.
@echo.
@goto :EOF
::====CLICK_THROUGH_UNINSTALL========================
::=====================================
:CHECKFILEEXISTS
if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON
:: DIR returns an error if file not found and zero if file is returned so we
:: have to turn things around a bit if we want to test for a file that SHOULD
:: be removed. In that case no error is a bad sign!
::
:: This sub-routine takes four params
:: - %1 filename or dirname to verify
:: - %2 - string for no error from dir. ie if we expect the file to exist
:: then pass GOOD. If we don't expect it then we pass BAD.
:: - %3 - string to output if DIR throws an error
:: - %4 - flag to indicate if 0 is an error or not
::@call :SET_VERBOSE
if defined VERBOSE @echo on
if defined VERBOSE @echo %*
dir %1 >nul 2>nul
if errorlevel 1 (
set _err=%ERRORLEVEL%
) else (
set _err=0
)
if %_err% EQU 0 (
@echo %TAB% %1 exists - %2 !
) else (
@echo %TAB% %1 not found - %3 !
)
if "%4"=="err_is_fail" (
if %_err% GTR 0 (
set /A XRESULT+=1
@echo XRESULT++
)
)
if "%4"=="no_err_is_fail" (
if %_err% EQU 0 (
set /A XRESULT+=1
@echo XRESULT++
)
)
call :RESET_ERRORLEVEL
@call :UNSET_VERBOSE
if defined DEBUG @echo Leaving %0
@goto :EOF
::===CHECKFILEEXISTS==================================
::=====================================
:CHECKSHAREDDLLS
if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON
@reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs > %TEMP%\shareddlls.txt
@grep --ignore-case --count firebird %TEMP%\shareddlls.txt > %TEMP%\shareddllscount.txt
set /p SHAREDDLLSCOUNT= < %TEMP%\shareddllscount.txt
if NOT defined DEBUG del /q %TEMP%\shareddll*.txt
if %SHAREDDLLSCOUNT% GTR 0 (
@echo %TAB% Oops - residue in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
set /A XRESULT+=1
@echo XRESULT++
)
call :RESET_ERRORLEVEL
if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===CHECKSHAREDDLLS===================
::=====================================
:COPY_INSTALL
@call :SET_VERBOSE_IF_DEBUG_ON
if defined DEBUG @echo Entering %0
::@call :SET_VERBOSE
if defined VERBOSE @echo on
:: ADIRNAME should normally be set during install and persist for uninstall
@if not defined ADIRNAME (
@if defined INSTALL_TIMESTAMP (
@if defined TESTNAME (
@set ADIRNAME=%FBINSTALLCOPYDIR%\%FIREBIRD_BASE_VER%_%INSTALLTYPE%_%TESTNAME%_%INSTALL_TIMESTAMP%
) else (
@set ADIRNAME=%FBINSTALLCOPYDIR%\%FIREBIRD_BASE_VER%_%INSTALLTYPE%_%INSTALL_TIMESTAMP%
)
) else (
@set ADIRNAME=%FBINSTALLCOPYDIR%\%FIREBIRD_BASE_VER%_Uninstall_%RUN_TIMESTAMP%
)
)
@if defined verbose @echo ADIRNAME is %ADIRNAME%
@mkdir %ADIRNAME% 2>nul
@if defined INSTALL (
@if not defined NOARCHIVE (
@echo %TAB% Copying Install to %ADIRNAME%
@xcopy /e /i /y %FIREBIRD% %ADIRNAME% > nul
@if errorlevel 1 (
@echo ERROR Failure executing xcopy /e /i /y %FIREBIRD% %ADIRNAME%
)
)
@copy %FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%-saved.inf %ADIRNAME%\install-saved.inf > nul
@copy %FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%.log %ADIRNAME%\install.log > nul
) else (
@echo %TAB% Copying uninstall log to %ADIRNAME%
@copy %FBINSTALLLOGDIR%\uninstall%RUN_TIMESTAMP%.log %ADIRNAME%\uninstall.log > nul
)
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===COPY_INSTALL======================
::=====================================
:CHECK_ENV
:: TODO - add more checks for the environment declared in SET_GLOBAL_ENV
if not exist %FBINST_EXEC% (
echo Cannot find %FBINST_EXEC%
exit /b 1
)
@goto :EOF
::===CHECK_ENV=========================
::=====================================
:RESET_ERRORLEVEL
:: ERRORLEVEL is an internal variable. We can see its value with
:: 'echo %ERRORLEVEL%' but if we try to reset its value with
:: SET ERRORLEVEL=0 we just create an env var called ERRORLEVEL which will
:: not have the same value as the internal ERRORLEVEL. We have to execute an
:: arbitrary command that cannot fail if we want to really reset the internal
:: variable.
@ver > nul
@goto :EOF
::===RESET_ERRORLEVEL==================
::=====================================
:SET_VERBOSE_IF_DEBUG_ON
:: The script is designed to allow turning VERBOSE on at the sub-routine level
:: If we set DEBUG globally then we should turn on VERBOSE automatically when
:: we enter a sub-routine
@if defined DEBUG (
@set VERBOSE=1
@echo on
)
@goto :EOF
::===SET_VERBOSE_IF_DEBUG_ON================
::=====================================
:SET_VERBOSE
@set VERBOSE=1
@goto :EOF
::===SET_VERBOSE================
::=====================================
:UNSET_VERBOSE
:: Unset VERBOSE before exiting each sub-routine.
:: and force echo off
@if NOT defined DEBUG (
@set VERBOSE=
@echo off
)
@goto :EOF
::===UNSET_VERBOSE================
::=====================================
:HELP
@echo off
@echo.
@more /e /t4 %~d0%~p0fbit-help.txt
@echo.
goto :EOF
::===HELP==============================
::=====================================
:ISS_ERROR
@echo.
@echo InnoSetup ErrorCode %1 from calling %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9
@echo Definition of Innosetup errorcode %1 is to be added later
@echo.
@goto :EOF
::======================================
::================================================================================================================
:: GENERIC SUPPORT ROUTINES FROM HERE TO END ======================================================================
::================================================================================================================
::=====================================
:GET_DATE
if NOT defined DEBUG @echo off
echo. | date | FIND "(mm" > NUL
if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD)
@goto :EOF
:ParseDate
for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do (
set %1=%%a
set %2=%%b
set YYYY=%%c
@goto:EOF)
::=====================================
::=====================================
:GET_TIME
if NOT defined DEBUG @echo off
for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do (
set hh=%%a
set nn=%%b
set ss=%%c
set ms=%%d
@goto :EOF)
::=====================================
::=====================================
:CLEAR_DT_VARS
if NOT defined DEBUG @echo off
set MM=
set DD=
set YYYY=
set hh=
set nn=
set ss=
set ms=
@goto :EOF
::=====================================
::=====================================
:TIMESTAMP
@call :GET_DATE
@call :GET_TIME
@set TIMESTAMP=%YYYY%%MM%%DD%%hh%%nn%%ss%
if defined DEBUG (@echo Timestamp set to %TIMESTAMP%)
call :CLEAR_DT_VARS
@goto :EOF
::=====================================
::==============================================================================
:: MAIN is always the last routine
::==============================================================================
::=====================================
:MAIN
@if defined DEBUG @echo Entering %0 %*
@call :SET_GLOBAL_ENV
@if /I "%1"=="help" (
@call :HELP
@goto :EOF
)
:: sometimes it is useful to just tidy up!
@if /I "%1"=="clean" (
@call :RUN_UNINSTALLER SCRIPTED CLEAN
@goto :EOF
)
@call :RUN_INSTALLER %*
@call :RUN_UNINSTALLER %*
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===MAIN==============================
:: CONTINUE with
:: - look at setting up different test recipes and naming them.
:: - Integrate innosetup exit codes and look at error handling
:: - Tidy up the relationship between DEBUG and VERBOSE.
:: - DEBUG should turn on VERBOSE?
:: - VERBOSE should be routine specific.?
:: - DEBUG should persist for entire script run?
:: NOTHING BEYOND THIS POINT===========
:EOF