@ECHO OFF

@rem Version  Date      Description
@rem -------  ----      -----------
@rem   1.0    20230202  First release version
@rem   1.1    20230304  Fix better lookup of current directory (otherwise
@rem                    affected when creating shortcuts to the .bat file).
@rem                    Also test and fix to work with /NEW parameter.
@rem   1.2    20251125  Add support for both Robex and Proficy Scheduler branded installers
@rem                    Also added support for different client and server install folders added.

@rem A script for both installing and updating ROB-EX
@rem Usage: InstallRobex.bat [/S] [/NEW]
@rem 
@rem /S:   Silent mode. Can be set as first parameter, in which case pause is never called
@rem /NEW: Set Install Mode to "new". Default is "update"

@rem Important:
@rem  1. The installer SetupRobex*.exe file must be located in the same
@rem     folder as this script!
@rem  2. To _not_ install certain components edit section with "set doXX=false" below
@rem  3. To specify Desktop client startup language edit section with "set LA=xx YY" below
@rem  4. To change installation directory edit section with "set INSTALL_ROOT_DIR=xx" below
@rem  5. Edit names of services to stop and start in by editing assignment of
@rem     respectively variables listOfServicesToStop and listOfServicesToStart below

@rem Set =false for components not to install
set doPlanner=true
set doPlannerIC=true
set doViewer=false
set doLicSrv=true
set doMuSrv=true

@rem Startup Language for Destkop Planner and Viewer
set LA=en IE

@REM Common root folder for all the different components
set INSTALL_ROOT_DIR=c:\program files (x86)\ROB-EX
@REM Server as default uses same root folder, but edit here if they are not the same
set SERVER_INSTALL_ROOT_DIR=%INSTALL_ROOT_DIR%

@rem List of services to stop - add additional integration clients to stop (place these before server is stopped)
set listOfServicesToStop=RobexClient_stdSite_1, ROB-EXServerG2Instance1x64, RobexLicenseServer1x64

@rem List of services to restart - add additional integration clients to start
set listOfServicesToStart=RobexLicenseServer1x64, ROB-EXServerG2Instance1x64, RobexClient_stdSite_1

@rem Install folder name for all the different components
set INSTALL_FOLDER_PLANNER=Planner
set INSTALL_FOLDER_PLANNERIC=PlannerIC
set INSTALL_FOLDER_VIEWER=Viewer
set INSTALL_FOLDER_LICSRV=LicenseServer
set INSTALL_FOLDER_MUSRV=ganttServerG2

@rem set INSTALL_FOLDER_MUSRV=ganttServerG2_2


@rem ***********************************
@rem ** Do not edit below this point  **
@rem ***********************************

@REM full path to working dir of the batch file
SET EXE_FOLDER=%~dp0

@rem Jar folder and jar name for all the different components
set JAR_FOLDER_PLANNER=lib\
set JAR_NAME_PLANNER=gantt.jar
set JAR_FOLDER_PLANNERIC=lib\
set JAR_NAME_PLANNERIC=gantt.jar
set JAR_FOLDER_VIEWER=lib\
set JAR_NAME_VIEWER=gantt.jar
set JAR_FOLDER_LICSRV=
set JAR_NAME_LICSRV=scheduler-license-floating-server.jar
set JAR_FOLDER_MUSRV=
set JAR_NAME_MUSRV=rbx-srv-boot.jar

REM investigate if we run interactively or not (silent) - must be first parameter
set RUN_INTERACTIVELY=true
if "%1"=="/S" (
  set RUN_INTERACTIVELY=false
  rem Change the position of command line parameters, i.e. %0 is set to %1, %1 is set to %2 etc.
  shift
)

@rem Installation Mode - specify "new" or "update" (without qoutes)
@rem Default is update - new is selected with startup parameter /NEW
set IM=update
if /I "%1"=="/NEW" (
  set IM=new
  rem Change the position of command line parameters, i.e. %0 is set to %1, %1 is set to %2 etc.
  shift
)

echo Install Mode: IM=%IM%

echo Administrative permissions required. Detecting permissions...

net session >nul 2>&1
if not %errorLevel% == 0 (
  echo [31mFailure: Current permissions are inadequate. Script will exit![0m
  goto exitWithError
) else (
  echo [32mOK - continuing[0m
)

Rem Find most recent installer EXE file
rem SET EXE_FOLDER=%userprofile%\Desktop
@rem fix that right click on .bat selecting "Run as administrator"
@rem will launch wit Windir as working dir
if %EXE_FOLDER%==%windir%\system32 SET EXE_FOLDER=%~dp0
REM Remove trailing backslash - if it exists
IF %EXE_FOLDER:~-1%==\ SET EXE_FOLDER=%EXE_FOLDER:~0,-1%

echo EXE_FOLDER=%EXE_FOLDER%

FOR /F "eol=| delims=" %%I IN ('DIR "%EXE_FOLDER%\Setup*_v*.exe" /A-D /B /O-D /TW 2^>nul') DO (
    SET pathToInstallerExe=%EXE_FOLDER%\%%I
    GOTO FoundFile
)
ECHO [31mNo Installer .exe file found in folder "%EXE_FOLDER%"![0m
set errorlevel=20
goto exitWithError

rem set pathToInstallerExe=%userprofile%\Desktop\SetupRobexTest_v7.2.exe

:FoundFile
ECHO Newest installer exe file is: %pathToInstallerExe%

set actionmsg=update
if /I %IM%==new set actionmsg=new install
if "%RUN_INTERACTIVELY%"=="false" goto okToStart

:approveStart

ECHO.
ECHO Proficy Scheduler/ROB-EX script based installation: %actionmsg%.
ECHO SERVER_INSTALL_ROOT_DIR: [33m%SERVER_INSTALL_ROOT_DIR%[0m.
ECHO INSTALL_ROOT_DIR: [33m%INSTALL_ROOT_DIR%[0m. Following components are included:
ECHO.

if %doPlanner%==true echo Planner (folder [33m"%INSTALL_FOLDER_PLANNER%"[0m)
if %doPlannerIC%==true echo PlannerIC (folder [33m"%INSTALL_FOLDER_PLANNERIC%"[0m)
if %doViewer%==true echo Viewer (folder [33m"%INSTALL_FOLDER_VIEWER%"[0m)
if %doLicSrv%==true echo License Server (folder [33m"%INSTALL_FOLDER_LICSRV%"[0m)
if %doMuSrv%==true echo Multiuser Server (folder [33m"%INSTALL_FOLDER_MUSRV%"[0m)

ECHO.
set choice=
set /p choice=Enter 'y' to continue %actionmsg% (any other key to exit): 
if not "%choice%"=="" set choice=%choice:~0,1%
if "%choice%"=="y" goto okToStart
goto normalExit

:okToStart

if /I %IM%==new GOTO doUpdateOkPlanner
@rem stop services
call :StopServices

echo errorlevel=%errorlevel%
if errorlevel 1 (
  GOTO exitWithError
)

@rem For IM=new make sure destination install folders are empty
:doUpdateOkPlanner
if not %doPlanner%==true goto doUpdateOkPlannerIC

set DEST_FILE=%INSTALL_ROOT_DIR%\%INSTALL_FOLDER_PLANNER%\%JAR_FOLDER_PLANNER%%JAR_NAME_PLANNER%

if /I %IM%==new (
  IF EXIST "%DEST_FILE%" (
    echo [31mCancelling NEW install since destination is not empty: "%DEST_FILE%"[0m
    GOTO exitWithError
  )
) else (
  ren "%DEST_FILE%" "%JAR_NAME_PLANNER%" 2>nul || (
    echo [31mFile "%DEST_FILE%" is locked by another user[0m
    GOTO exitWithError
  )
)

:doUpdateOkPlannerIC
if not %doPlannerIC%==true goto doUpdateOkViewer

set DEST_FILE=%INSTALL_ROOT_DIR%\%INSTALL_FOLDER_PLANNERIC%\%JAR_FOLDER_PLANNERIC%%JAR_NAME_PLANNERIC%

if /I %IM%==new (
  IF EXIST "%DEST_FILE%" (
    echo [31mCancelling NEW install since destination is not empty: "%DEST_FILE%"[0m
    GOTO exitWithError
  )
) else (
  ren "%DEST_FILE%" "%JAR_NAME_PLANNERIC%" 2>nul || (
    echo [31mFile "%DEST_FILE%" is locked by another user[0m
    GOTO exitWithError
  )
)

:doUpdateOkViewer
if not %doViewer%==true goto doUpdateOkLicSrv

set DEST_FILE=%INSTALL_ROOT_DIR%\%INSTALL_FOLDER_VIEWER%\%JAR_FOLDER_VIEWER%%JAR_NAME_VIEWER%

if /I %IM%==new (
  IF EXIST "%DEST_FILE%" (
    echo [31mCancelling NEW install since destination is not empty: "%DEST_FILE%"[0m
    GOTO exitWithError
  )
) else (
  ren "%DEST_FILE%" "%JAR_NAME_VIEWER%" 2>nul || (
    echo [31mFile "%DEST_FILE%" is locked by another user[0m
    GOTO exitWithError
  )
)

:doUpdateOkLicSrv
if not %doLicSrv%==true goto doUpdateOkMuSrv

set DEST_FILE=%SERVER_INSTALL_ROOT_DIR%\%INSTALL_FOLDER_LICSRV%\%JAR_FOLDER_LICSRV%%JAR_NAME_LICSRV%

if /I %IM%==new (
  IF EXIST "%DEST_FILE%" (
    echo [31mCancelling NEW install since destination is not empty: "%DEST_FILE%"[0m
    GOTO exitWithError
  )
) else (
  ren "%DEST_FILE%" "%JAR_NAME_LICSRV%" 2>nul || (
    echo [31mFile "%DEST_FILE%" is locked by another user[0m
    GOTO exitWithError
  )
)

:doUpdateOkMuSrv
if not %doMuSrv%==true goto updateOkChecked

set DEST_FILE=%SERVER_INSTALL_ROOT_DIR%\%INSTALL_FOLDER_MUSRV%\%JAR_FOLDER_MUSRV%%JAR_NAME_MUSRV%

if /I %IM%==new (
  IF EXIST "%DEST_FILE%" (
    echo [31mCancelling NEW install since destination is not empty: "%DEST_FILE%"[0m
    GOTO exitWithError
  )
) else (
  ren "%DEST_FILE%" "%JAR_NAME_MUSRV%" 2>nul || (
    echo [31mFile "%DEST_FILE%" is locked by another user[0m
    GOTO exitWithError
  )
)

:updateOkChecked

:doInstallUpdatePlanner
if not %doPlanner%==true goto doInstallUpdatePlannerIC

@rem <------ Installation of Desktop Planner ---------->
set DEST_FOLDER=%INSTALL_ROOT_DIR%\%INSTALL_FOLDER_PLANNER%
set CP=planner

if /I %IM%==update (
  @rem Check again if file is still not locked
  ren "%DEST_FOLDER%\%JAR_FOLDER_PLANNERIC%%JAR_NAME_PLANNER%" "%JAR_NAME_PLANNER%" 2>nul || (
    echo [31mFile "%DEST_FOLDER%\%JAR_FOLDER_PLANNER%%JAR_NAME_PLANNER%" is locked by another user[0m
    GOTO exitWithError
  )
)

@rem carry out the actual installation
call :RunInstaller "/S /IM=%IM% /CP=%CP%" "%LA%" "%DEST_FOLDER%"

if errorlevel 1 (
  echo [31mAn error %errorlevel% occured during installation of: "/IM=%IM%" "/CP=%CP%" "/D=%DEST_FOLDER%"[0m
  GOTO exitWithError
)

:doInstallUpdatePlannerIC
if not %doPlannerIC%==true goto doInstallUpdateViewer

@rem <------ Installation of Planner Integration Client ---------->
set DEST_FOLDER=%INSTALL_ROOT_DIR%\%INSTALL_FOLDER_PLANNERIC%
set CP=planneric

if /I %IM%==update (
  @rem Check again if file is still not locked
  ren "%DEST_FOLDER%\%JAR_FOLDER_PLANNERIC%%JAR_NAME_PLANNERIC%" "%JAR_NAME_PLANNERIC%" 2>nul || (
    echo [31mFile "%DEST_FOLDER%\%JAR_FOLDER_PLANNERIC%%JAR_NAME_PLANNERIC%" is locked by another user[0m
    GOTO exitWithError
  )
)

@rem carry out the actual installation
call :RunInstaller "/S /IM=%IM% /CP=%CP%" "%LA%" "%DEST_FOLDER%"

if errorlevel 1 (
  echo [31mAn error %errorlevel% occured during installation of: "/IM=%IM%" "/CP=%CP%" "/D=%DEST_FOLDER%"[0m
  GOTO exitWithError
)

:doInstallUpdateViewer
if not %doViewer%==true goto doInstallUpdateLicSrv

@rem <------ Installation of Desktop Viewer ---------->
set DEST_FOLDER=%INSTALL_ROOT_DIR%\%INSTALL_FOLDER_VIEWER%
set CP=viewer

if /I %IM%==update (
  @rem Check again if file is still not locked
  ren "%DEST_FOLDER%\%JAR_FOLDER_VIEWER%%JAR_NAME_VIEWER%" "%JAR_NAME_VIEWER%" 2>nul || (
    echo [31mFile "%DEST_FOLDER%\%JAR_FOLDER_VIEWER%%JAR_NAME_VIEWER%" is locked by another user[0m
    GOTO exitWithError
  )
)

@rem carry out the actual installation
call :RunInstaller "/S /IM=%IM% /CP=%CP%" "%LA%" "%DEST_FOLDER%"

if errorlevel 1 (
  echo [31mAn error %errorlevel% occured during installation of: "/IM=%IM%" "/CP=%CP%" "/D=%DEST_FOLDER%"[0m
  GOTO exitWithError
)

:doInstallUpdateLicSrv
if not %doLicSrv%==true goto doInstallUpdateMuSrv

@rem <------ Installation of License Server ---------->
set DEST_FOLDER=%SERVER_INSTALL_ROOT_DIR%\%INSTALL_FOLDER_LICSRV%
set CP=licsrv

if /I %IM%==update (
  @rem Check again if file is still not locked
  ren "%DEST_FOLDER%\%JAR_FOLDER_LICSRV%%JAR_NAME_LICSRV%" "%JAR_NAME_LICSRV%" 2>nul || (
    echo [31mFile "%DEST_FOLDER%\%JAR_FOLDER_LICSRV%%JAR_NAME_LICSRV%" is locked by another user[0m
    GOTO exitWithError
  )
)

@rem carry out the actual installation
call :RunInstaller "/S /IM=%IM% /CP=%CP%" "%LA%" "%DEST_FOLDER%"

if errorlevel 1 (
  echo [31mAn error %errorlevel% occured during installation of: "/IM=%IM%" "/CP=%CP%" "/D=%DEST_FOLDER%"[0m
  GOTO exitWithError
)

:doInstallUpdateMuSrv
if not %doMuSrv%==true goto normalComplete

@rem <------ Installation of Multiuser Server ---------->
set DEST_FOLDER=%SERVER_INSTALL_ROOT_DIR%\%INSTALL_FOLDER_MUSRV%
set CP=musrv
@rem Database name
set DBN=GanttMultiuser
@rem Database Server
set DBS=localhost

if /I %IM%==update (
  @rem Check again if file is still not locked
  ren "%DEST_FOLDER%\%JAR_FOLDER_MUSRV%%JAR_NAME_MUSRV%" "%JAR_NAME_MUSRV%" 2>nul || (
    echo [31mFile "%DEST_FOLDER%\%JAR_FOLDER_MUSRV%%JAR_NAME_MUSRV%" is locked by another user[0m
    GOTO exitWithError
  )
)

@rem carry out the actual installation
call :RunInstallerMuSrv "/S /IM=%IM% /CP=%CP%" "%LA%" "%DBN%" "%DBS%" "%DEST_FOLDER%"

if errorlevel 1 (
  echo [31mAn error %errorlevel% occured during installation of: "/IM=%IM%" "/CP=%CP%" "/D=%DEST_FOLDER%"[0m
  GOTO exitWithError
)

:normalComplete

@rem start services
call :StartServices

:normalExit

echo.
if not "%RUN_INTERACTIVELY%"=="false" pause
GOTO :EOF

:exitWithError

echo.
if not "%RUN_INTERACTIVELY%"=="false" pause
exit /B %errorlevel%

:RunInstaller

REM get rid of qoutes on some of the input parameters using eg %~1
REM for others add command switch but keep qoutes
set parm1=%~1
@ rem LA
set parm2=%2
set parm2=/LA=%parm2%

set parm3=
set parm4=

@ rem D
set parmD=%~3

GOTO LookupInstaller

:RunInstallerMuSrv

REM get rid of qoutes on some of the input parameters using eg %~1
REM for others add command switch but keep qoutes
set parm1=%~1
@ rem LA
set parm2=%2
set parm2=/LA=%parm2%
@ rem DBN
set parm3=%3
set parm3=/DBN=%parm3%
@ rem DBS
set parm4=%4
set parm4=/DBS=%parm4%
@ rem D
set parmD=%~5

:LookupInstaller
ECHO Newest installer exe file is: %pathToInstallerExe%

set PARAMS_TO_USE=%parm1% %parm2% %parm3% %parm4% /D=%parmD%
REM set PARAMS_TO_USE=%1 %2 %3
echo Params2: %PARAMS_TO_USE%
"%pathToInstallerExe%" %PARAMS_TO_USE%

if errorlevel 1 (
  echo [31mAn error %errorlevel% occured during installation of: "%PARAMS_TO_USE%"[0m
  REM pause
  exit /B %errorlevel%
)

setlocal EnableDelayedExpansion

set imText=installed
if not %IM%==new set imText=updated
echo [32mSuccessfully !imText! "%parmD%"[0m
echo.

GOTO :EOF

:StopServices

echo.
for %%x in ( %listOfServicesToStop% ) do (
     @rem check if service exists
	 SC QUERY "%%x" > NUL
     IF not ERRORLEVEL 1 (
       echo Stopping service "%%x"
       net stop "%%x" > NUL 2>&1
	 ) else (
       echo [31mUnable to stop non-existing service "%%x"[0m
       if /I %IM%==new echo [31mContinuing[0m
       if /I %IM%==update echo [31mScript will exit![0m
       if /I %IM%==update exit /B 1060
	 )
   )
echo.

REM net stop RobexLicenseServer1x64 > NUL 2>&1
REM net stop ROB-EXServerG2Instance1x64 > NUL 2>&1
REM net stop RobexClient_stdSite_1 > NUL 2>&1

@rem make sure that tray icon service is not running
taskkill /f /im javaw.exe > NUL 2>&1

exit /B 0

GOTO :EOF

:StartServices

echo.
for %%x in ( %listOfServicesToStart% ) do (
     @rem check if service exists
	 SC QUERY "%%x" > NUL
     IF not ERRORLEVEL 1 (
       echo Starting service "%%x"
       net start "%%x" > NUL 2>&1
       
       @rem Sleep when starting multiuser server service to allow it to fully start ahead of clients
       Echo.%%x | findstr /I /C:"ServerG2Instance">nul && (
         Echo.Sleeping to allow server to start
         @rem ping 127.0.0.1 -n 15 > nul
		 Call :CheckForMuServerStartInLogfile
       )
	 ) else (
       echo [31mUnable to start non-existing service "%%x" - continuing...[0m
	 )
   )
echo.

GOTO :EOF

:CheckForMuServerStartInLogfile

set MU_LOGFILE=%SERVER_INSTALL_ROOT_DIR%\%INSTALL_FOLDER_MUSRV%\logs\rbx_srv_log.txt

IF NOT EXIST "%MU_LOGFILE%" goto NoLogFile

echo Waiting for server started in log-file "%MU_LOGFILE%"

@rem start Powershell script to wait for server started message in log-file 
@rem PowerShell v3 is required as minimum, so the script is prepared that this can happen

@PowerShell -NoProfile -ExecutionPolicy Bypass  ^
   $maxWaitLoops = 12; ^
   for ($j = 0; $j -lt $maxWaitLoops; $j++)  ^
   {  ^
     Start-Sleep -s 5; ^
     $fpath = '%MU_LOGFILE%';  ^
     $var = Get-content -tail 40 $fpath ^| Select-String -InputObject {$_} -Pattern 'RobexServer started \(Srv'; ^
     if ($var) { ^
       break ^
     } ^
	 Write-Host -NoNewLine '.'; ^
   } ^
   Write-Host '.'; ^
%End PowerShell%

if %errorlevel% LEQ -1 (
  echo neg errorlevel=%errorlevel%
  @ren Powershell script failed - likely server only support PS 2.0
  ping 127.0.0.1 -n 30 > nul
)
if errorlevel 1 (
  echo pos errorlevel=%errorlevel%
  @ren Powershell script failed - likely server only support PS 2.0
  ping 127.0.0.1 -n 30 > nul
)

GOTO LogFileCheckComplete

:NoLogFile
ping 127.0.0.1 -n 30 > nul

:LogFileCheckComplete
GOTO :EOF

REM :DeQuote
REM for /f "delims=" %%A in ('echo %%%1%%') do set %1=%%~A
REM Goto :eof
