WizardKit/.bin/Scripts/Launch.cmd
Alan Mason 19f744f8f8 Avoid double pause in Launch.cmd
If Launch.cmd aborted it would cause the launcher to abort as well.
If the error was handled by Launch.cmd then we can assume the launcher ran correctly.
2017-11-22 15:33:29 -08:00

512 lines
No EOL
14 KiB
Batchfile

:: Wizard Kit: Wrapper for launching programs and scripts.
::
:: Some features:
:: * If the OS is 64-bit then the WorkingDir is scanned for a 64-bit version of the programs
:: * Allows for centralized terminal emulation settings management
:: * Allows for smaller "launcher" scripts to be used as they will rely on this script.
@echo off
if defined DEBUG (@echo on)
:Init
setlocal EnableDelayedExpansion
title Wizard Kit: Launcher
pushd "%~dp0"
call :FindBin
call :DeQuote L_ITEM
call :DeQuote L_PATH
call :DeQuote L_TYPE
:SetVariables
rem Set variables using settings\main.py file
set "SETTINGS=%bin%\Scripts\settings\main.py"
for %%v in (ARCHIVE_PASSWORD KIT_NAME_FULL OFFICE_SERVER_IP QUICKBOOKS_SERVER_IP) do (
set "var=%%v"
for /f "tokens=* usebackq" %%f in (`findstr "!var!=" %SETTINGS%`) do (
set "_v=%%f"
set "_v=!_v:*'=!"
set "%%v=!_v:~0,-1!"
)
)
rem Set ARCH to 32 as a gross assumption and check for x86_64 status
set ARCH=32
if /i "%PROCESSOR_ARCHITECTURE%" == "AMD64" set "ARCH=64"
set "SEVEN_ZIP=%bin%\7-Zip\7za.exe"
set "CON=%bin%\ConEmu\ConEmu.exe"
set "FASTCOPY=%bin%\FastCopy\FastCopy.exe"
set "POWERSHELL=%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe"
set "PYTHON=%bin%\Python\x32\python.exe"
if %ARCH% equ 64 (
set "SEVEN_ZIP=%bin%\7-Zip\7za64.exe"
set "CON=%bin%\ConEmu\ConEmu64.exe"
set "FASTCOPY=%bin%\FastCopy\FastCopy64.exe"
set "PYTHON=%bin%\Python\x64\python.exe"
)
:UpdateTitle
rem Sets title using KIT_NAME_FULL from settings\main.py (unless %window_title% already set)
if defined window_title (
title %window_title%
) else (
set "window_title=%*"
if not defined window_title set "window_title=Launcher"
set "window_title=%KIT_NAME_FULL%: %window_title%"
title %window_title%
)
:CheckUsage
rem Check for empty passed variables
if not defined L_TYPE (goto Usage)
if not defined L_PATH (goto Usage)
if not defined L_ITEM (goto Usage)
rem Assume if not "True" then False (i.e. undefine variable)
if /i not "%L_ELEV%" == "True" (set "L_ELEV=")
if /i not "%L_NCMD%" == "True" (set "L_NCMD=")
:RelaunchInConEmu
set RELOAD_IN_CONEMU=True
if defined ConEmuBuild set "RELOAD_IN_CONEMU="
if defined L_NCMD set "RELOAD_IN_CONEMU="
if "%L_TYPE%" == "PSScript" set "RELOAD_IN_CONEMU="
if "%L_TYPE%" == "PyScript" set "RELOAD_IN_CONEMU="
if defined RELOAD_IN_CONEMU (
set "con_args=-new_console:n"
rem If in DEBUG state then force ConEmu to stay open
if defined DEBUG (set "con_args=!con_args! -new_console:c")
start "" "%CON%" -run ""%~0" %*" !con_args! || goto ErrorUnknown
exit /b 0
)
:CheckLaunchType
rem Jump to the selected launch type or show usage
if /i "%L_TYPE%" == "Console" (goto LaunchConsole)
if /i "%L_TYPE%" == "Folder" (goto LaunchFolder)
if /i "%L_TYPE%" == "Office" (goto LaunchOffice)
if /i "%L_TYPE%" == "QuickBooks" (goto LaunchQuickBooksSetup)
if /i "%L_TYPE%" == "Program" (goto LaunchProgram)
if /i "%L_TYPE%" == "PSScript" (goto LaunchPSScript)
if /i "%L_TYPE%" == "PyScript" (goto LaunchPyScript)
goto Usage
:LaunchConsole
rem Prep
call :ExtractOrFindPath || goto ErrorProgramNotFound
rem Check for 64-bit prog (if running on 64-bit system)
set "prog=%_path%\%L_ITEM%"
if %ARCH% equ 64 (
if exist "%_path%\%L_ITEM:.=64.%" set "prog=%_path%\%L_ITEM:.=64.%"
)
if not exist "%prog%" goto ErrorProgramNotFound
rem Run program
popd && pushd "%_path%"
if defined L_NCMD (
goto LaunchConsoleNative
) else (
goto LaunchConsoleConEmu
)
:LaunchConsoleConEmu
rem Prep
set "con_args=-new_console:n"
if defined DEBUG (set "con_args=%con_args% -new_console:c")
if defined L_ELEV (set "con_args=%con_args% -new_console:a")
rem Run
start "" "%CON%" -run "%prog%" %L_ARGS% %con_args% || goto ErrorUnknown
goto Exit
:LaunchConsoleNative
rem Run
start "" "%prog%" %L_ARGS% || goto ErrorUnknown
goto Exit
:LaunchFolder
rem Prep
call :ExtractOrFindPath || goto ErrorProgramNotFound
rem Run
start "" "explorer.exe" "%_path%" || goto ErrorUnknown
goto Exit
:LaunchOffice
call "%bin%\Scripts\init_client_dir.cmd" /Office
set "_odt=False"
if %L_PATH% equ 2013 (set "_odt=True")
if %L_PATH% equ 2016 (set "_odt=True")
if "%_odt%" == "True" (
goto LaunchOfficeODT
) else (
goto LaunchOfficeSetup
)
:LaunchOfficeODT
rem Prep
set "args=-aoa -bso0 -bse0 -bsp0 -p%ARCHIVE_PASSWORD%"
set "config=%L_ITEM%"
set "dest=%client_dir%\Office\%L_PATH%"
set "odt_exe=%L_PATH%\setup.exe"
set "source=%cbin%\_Office.7z"
rem Extract
if not exist "%source%" (goto ErrorODTSourceNotFound)
"%SEVEN_ZIP%" e "%source%" %args% -o"%dest%" %odt_exe% %config% || exit /b 1
"%systemroot%\System32\ping.exe" -n 2 127.0.0.1>nul
rem Verify
if not exist "%dest%\setup.exe" (goto ErrorODTSourceNotFound)
if not exist "%dest%\%config%" (goto ErrorODTSourceNotFound)
pushd "%dest%"
rem Run
rem # The line below jumps to ErrorUnknown even when it runs correctly??
rem start "" "setup.exe" /configure %L_ITEM% || popd & goto ErrorUnknown
rem # Going to assume it extracted correctly and blindly start setup.exe
start "" "setup.exe" /configure %config%
popd
goto Exit
:LaunchOfficeSetup
rem Prep
echo Copying setup file(s) for %L_ITEM%...
set "fastcopy_args=/cmd=diff /no_ui /auto_close"
set "product=%L_PATH%\%L_ITEM%"
set "product_name=%L_ITEM%"
call :GetBasename product_name || goto ErrorBasename
set "source=\\%OFFICE_SERVER%\Office\%product%"
set "dest=%client_dir%\Office"
rem Verify
if not exist "%source%" (goto ErrorOfficeSourceNotFound)
rem Copy
start "" /wait "%FASTCOPY%" %fastcopy_args% "%source%" /to="%dest%\"
rem Run
if exist "%dest%\%product_name%\setup.exe" (
start "" "%dest%\%product_name%\setup.exe" || goto ErrorUnknown
) else if "%product_name:~-3,3%" == "exe" (
start "" "%dest%\%product_name%" || goto ErrorUnknown
) else if "%product_name:~-3,3%" == "msi" (
start "" "%dest%\%product_name%" || goto ErrorUnknown
) else (
rem Office source not supported by this script
goto ErrorOfficeUnsupported
)
goto Exit
:LaunchProgram
rem Prep
call :ExtractOrFindPath || goto ErrorProgramNotFound
rem Check for 64-bit prog (if running on 64-bit system)
set "prog=%_path%\%L_ITEM%"
if %ARCH% equ 64 (
if exist "%_path%\%L_ITEM:.=64.%" set "prog=%_path%\%L_ITEM:.=64.%"
)
if not exist "%prog%" goto ErrorProgramNotFound
rem Run
popd && pushd "%_path%"
if defined L_ELEV (
goto LaunchProgramElev
) else (
goto LaunchProgramUser
)
:LaunchProgramElev
rem Prep
call :DeQuote prog
call :DeQuote L_ARGS
rem Create VB script
mkdir "%bin%\tmp" 2>nul
echo Set UAC = CreateObject^("Shell.Application"^) > "%bin%\tmp\Elevate.vbs"
echo UAC.ShellExecute "%prog%", "%L_ARGS%", "", "runas", 1 >> "%bin%\tmp\Elevate.vbs"
rem Run
"%systemroot%\System32\cscript.exe" //nologo "%bin%\tmp\Elevate.vbs" || goto ErrorUnknown
goto Exit
:LaunchProgramUser
rem Run
start "" "%prog%" %L_ARGS% || goto ErrorUnknown
goto Exit
:LaunchPSScript
rem Prep
call :ExtractOrFindPath || goto ErrorProgramNotFound
set "script=%_path%\%L_ITEM%"
set "ps_args=-ExecutionPolicy Bypass -NoProfile"
rem Verify
if not exist "%script%" goto ErrorScriptNotFound
rem Run
popd && pushd "%_path%"
if defined L_ELEV (
goto LaunchPSScriptElev
) else (
goto LaunchPSScriptUser
)
:LaunchPSScriptElev
rem Prep
call :DeQuote script
rem Create VB script
mkdir "%bin%\tmp" 2>nul
echo Set UAC = CreateObject^("Shell.Application"^) > "%bin%\tmp\Elevate.vbs"
if defined L_NCMD (
rem use Powershell's window instead of %CON%
echo UAC.ShellExecute "%POWERSHELL%", "%ps_args% -File "%script%"", "", "runas", 3 >> "%bin%\tmp\Elevate.vbs"
) else (
echo UAC.ShellExecute "%CON%", "-run %POWERSHELL% %ps_args% -File "%script%" -new_console:n", "", "runas", 1 >> "%bin%\tmp\Elevate.vbs"
)
rem Run
"%systemroot%\System32\cscript.exe" //nologo "%bin%\tmp\Elevate.vbs" || goto ErrorUnknown
goto Exit
:LaunchPSScriptUser
rem Run
if defined L_NCMD (
start "" "%POWERSHELL%" %ps_args% -File "%script%" || goto ErrorUnknown
) else (
start "" "%CON%" -run "%POWERSHELL%" %ps_args% -File "%script%" -new_console:n || goto ErrorUnknown
)
goto Exit
:LaunchPyScript
rem Prep
call :ExtractOrFindPath || goto ErrorProgramNotFound
set "script=%_path%\%L_ITEM%"
rem Verify
if not exist "%script%" goto ErrorScriptNotFound
rem Run
if defined L_ELEV (
goto LaunchPyScriptElev
) else (
goto LaunchPyScriptUser
)
:LaunchPyScriptElev
rem Prep
call :DeQuote script
rem Create VB script
mkdir "%bin%\tmp" 2>nul
echo Set UAC = CreateObject^("Shell.Application"^) > "%bin%\tmp\Elevate.vbs"
if defined L_NCMD (
echo UAC.ShellExecute "%PYTHON%", "%script%", "", "runas", 3 >> "%bin%\tmp\Elevate.vbs"
) else (
echo UAC.ShellExecute "%CON%", "-run %PYTHON% %script% -new_console:n", "", "runas", 1 >> "%bin%\tmp\Elevate.vbs"
)
rem Run
"%systemroot%\System32\cscript.exe" //nologo "%bin%\tmp\Elevate.vbs" || goto ErrorUnknown
goto Exit
:LaunchPyScriptUser
if defined L_NCMD (
start "" "%PYTHON%" "%script%" || goto ErrorUnknown
) else (
start "" "%CON%" -run "%PYTHON%" "%script%" -new_console:n || goto ErrorUnknown
)
goto Exit
:LaunchQuickBooksSetup
rem Prep
call "%bin%\Scripts\init_client_dir.cmd" /QuickBooks
set "fastcopy_args=/cmd=diff /no_ui /auto_close"
set "product=%L_PATH%\%L_ITEM%"
set "product_name=%L_ITEM%"
call :GetBasename product_name || goto ErrorBasename
set "source=\\%QUICKBOOKS_SERVER_IP%\QuickBooks\%product%"
set "dest=%client_dir%\QuickBooks"
rem Verify
if not exist "%source%" (goto ErrorQuickBooksSourceNotFound)
rem Copy
echo Copying setup file(s) for %L_ITEM%...
start "" /wait "%FASTCOPY%" %fastcopy_args% "%source%" /to="%dest%\"
rem Run
if exist "%dest%\%product_name%\Setup.exe" (
pushd "%dest%\%product_name%"
start "" "%dest%\%product_name%\Setup.exe" || goto ErrorUnknown
popd
) else (
rem QuickBooks source not supported by this script
goto ErrorQuickBooksUnsupported
)
goto Exit
:Usage
echo.
echo.Usage (via defined variables):
echo. L_TYPE L_PATH L_ITEM L_ARGS
echo. Console Working Dir Program Args [L_ELEV] [L_NCMD]
echo. Folder Folder '.' [L_NCMD]
echo. Office Year Product [L_NCMD]
echo. QuickBooks Year Product [L_NCMD]
echo. Program Working Dir Program Args [L_ELEV] [L_NCMD]
echo. PSScript Scripts Script [L_ELEV] [L_NCMD]
echo. PyScript Scripts Script [L_ELEV] [L_NCMD]
echo.
goto Abort
:: Functions ::
:DeQuote
rem Code taken from http://ss64.com/nt/syntax-dequote.html
if not defined %1 (@exit /b 1)
for /f "delims=" %%a in ('echo %%%1%%') do set %1=%%~a
@exit /b 0
:ExtractCBin
rem Extract %cbin% archive into %bin%
echo Extracting "%L_PATH%"...
set "source=%cbin%\%L_PATH%.7z"
set "dest=%bin%\%L_PATH%"
set "args=-aos -bso0 -bse0 -bsp0 -p%ARCHIVE_PASSWORD%"
if defined DEBUG (set "args=-aos -p%ARCHIVE_PASSWORD%")
"%SEVEN_ZIP%" x "%source%" %args% -o"%dest%" %L_7ZIP% || exit /b 1
ping.exe -n 2 127.0.0.1>nul
exit /b 0
:FindBin
rem Checks the current directory and all parents for the ".bin" folder
rem NOTE: Has not been tested for UNC paths
set bin=
pushd "%~dp0"
:FindBinInner
if exist ".bin" (goto FindBinDone)
if "%~d0\" == "%cd%" (popd & @exit /b 1)
cd ..
goto FindBinInner
:FindBinDone
set "bin=%cd%\.bin"
set "cbin=%cd%\.cbin"
popd
@exit /b 0
:GetBasename
rem Loop over passed variable to remove all text left of the last '\' character
rem NOTE: This function should be called as 'call :GetBasename VarName || goto ErrorBasename' to catch variables that become empty.
for /f "delims=" %%a in ('echo %%%1%%') do (set "_tmp=%%~a")
:GetBasenameInner
set "_tmp=%_tmp:*\=%"
if not defined _tmp (@exit /b 1)
if not "%_tmp%" == "%_tmp:*\=%" (goto GetBasenameInner)
:GetBasenameDone
set "%1=%_tmp%"
@exit /b 0
:ExtractOrFindPath
rem Test L_PATH in the following order:
rem 1: %cbin%\L_PATH.7z (which will be extracted to %bin%\L_PATH)
rem 2: %bin%\L_PATH
rem 3. %L_PATH% (i.e. treat L_PATH as an absolute path)
rem NOTE: This function should be called as 'call :ExtractOrFindPath || goto ErrorProgramNotFound' to catch invalid paths.
set _path=
if exist "%cbin%\%L_PATH%.7z" (
call :ExtractCBin
) else if exist "%cbin%\%L_PATH%\%L_ITEM:~0,-4%.7z" (
call :ExtractCBin
)
if exist "%bin%\%L_PATH%" (set "_path=%bin%\%L_PATH%")
if not defined _path (set "_path=%L_PATH%")
rem Raise error if path is still not available
if not exist "%_path%" (exit /b 1)
exit /b 0
:: Errors ::
:ErrorBasename
echo.
echo ERROR: GetBasename resulted in an empty variable.
goto Abort
:ErrorNoBin
echo.
echo ERROR: ".bin" folder not found.
goto Abort
:ErrorODTSourceNotFound
echo.
echo ERROR: Office Deployment Tool source not found.
goto Abort
:ErrorOfficeSourceNotFound
echo.
echo ERROR: Office source "%L_ITEM%" not found.
goto Abort
:ErrorOfficeUnsupported
rem Source is not an executable nor is a folder with a setup.exe file inside. Open explorer to local setup file(s) instead.
echo.
echo ERROR: Office version not supported by this script.
start "" "explorer.exe" "%client_dir%\Office"
goto Abort
:ErrorQuickBooksSourceNotFound
echo.
echo ERROR: QuickBooks source "%L_ITEM%" not found.
goto Abort
:ErrorQuickBooksUnsupported
rem Source is not an executable nor is a folder with a setup.exe file inside. Open explorer to local setup file(s) instead.
echo.
echo ERROR: QuickBooks version not supported by this script.
start "" "explorer.exe" "%client_dir%\QuickBooks"
goto Abort
:ErrorProgramNotFound
echo.
echo ERROR: Program "%prog%" not found.
goto Abort
:ErrorScriptNotFound
echo.
echo ERROR: Script "%script%" not found.
goto Abort
:ErrorUnknown
echo.
echo ERROR: Unknown error encountered.
goto Abort
:Abort
rem Handle color theme for both the native console and ConEmu
if defined L_NCMD (
color 4e
) else (
color c4
)
echo Aborted.
echo.
echo DETAILS: L_TYPE: %L_TYPE%
echo. L_PATH: %L_PATH%
echo. L_ITEM: %L_ITEM%
echo. L_ARGS: %L_ARGS%
echo. L_ELEV: %L_ELEV%
echo. L_NCMD: %L_NCMD%
echo. CON: %CON%
echo. DEBUG: %DEBUG%
echo. PYTHON: %PYTHON%
echo Press any key to exit...
pause>nul
rem reset color and reset errorlevel to 0
rem NOTE: This is done to avoid causing a ErrorLaunchCMD in the launcher.cmd
color
goto Exit
:: Cleanup and exit ::
:Exit
popd
endlocal
exit /b %errorlevel%