gibMacOS/gibMacOS.bat

330 lines
10 KiB
Batchfile
Raw Normal View History

2018-09-26 06:16:18 +02:00
@echo off
setlocal enableDelayedExpansion
REM Setup initial vars
2020-07-03 16:05:41 +02:00
set "script_name="
2018-09-26 06:16:18 +02:00
set "thisDir=%~dp0"
2019-03-14 18:47:40 +01:00
set /a tried=0
2019-03-14 19:09:32 +01:00
set "toask=yes"
2020-07-05 18:44:57 +02:00
set "pause_on_error=yes"
2019-09-15 05:31:23 +02:00
set "py2v="
set "py2path="
set "py3v="
set "py3path="
set "pypath="
REM use_py3:
REM TRUE = Use if found, use py2 otherwise
REM FALSE = Use py2
REM FORCE = Use py3
set "use_py3=TRUE"
2018-09-26 06:16:18 +02:00
2020-07-03 15:36:27 +02:00
REM Get the system32 (or equivalent) path
call :setcomspec
set "syspath=%ComSpec:cmd.exe=%"
2019-03-14 18:47:40 +01:00
goto checkscript
:checkscript
2019-02-21 20:29:15 +01:00
REM Check for our script first
2020-07-03 16:05:41 +02:00
set "looking_for=!script_name!"
if "!script_name!" == "" (
set "looking_for=%~n0.py or %~n0.command"
set "script_name=%~n0.py"
if not exist "!thisDir!\!script_name!" (
set "script_name=%~n0.command"
)
)
2019-02-21 20:29:15 +01:00
if not exist "!thisDir!\!script_name!" (
2020-07-03 16:05:41 +02:00
echo Could not find !looking_for!.
2019-02-21 20:29:15 +01:00
echo Please make sure to run this script from the same directory
2020-07-03 16:05:41 +02:00
echo as !looking_for!.
2019-02-21 20:29:15 +01:00
echo.
echo Press [enter] to quit.
pause > nul
exit /b
)
2019-03-14 18:47:40 +01:00
goto checkpy
2019-02-21 20:29:15 +01:00
2020-07-03 15:36:27 +02:00
:setcomspec
REM Helper method to return the "proper" path to cmd.exe, reg.exe, and where.exe by walking the ComSpec var
2020-07-08 19:23:14 +02:00
REM Prep the LF variable to use the "line feed" approach
(SET LF=^
%=this line is empty=%
)
2020-07-03 15:36:27 +02:00
REM Strip double semi-colons
call :undouble "ComSpec" ";"
set "testpath=%ComSpec:;=!LF!%"
REM Let's walk each path and test if cmd.exe, reg.exe, and where.exe exist there
2020-07-03 16:05:41 +02:00
set /a found=0
2020-07-08 19:23:14 +02:00
for /f "tokens=* delims=" %%i in ("!testpath!") do (
2020-07-03 15:36:27 +02:00
REM Only continue if we haven't found it yet
if NOT "%%i" == "" (
2020-07-03 16:05:41 +02:00
if !found! lss 1 (
2020-07-03 15:36:27 +02:00
set "temppath=%%i"
REM Remove "cmd.exe" from the end if it exists
if /i "!temppath:~-7!" == "cmd.exe" (
set "temppath=!temppath:~0,-7!"
)
REM Pad the end with a backslash if needed
if NOT "!temppath:~-1!" == "\" (
set "temppath=!temppath!\"
)
REM Let's see if cmd, reg, and where exist there - and set it if so
if EXIST "!temppath!cmd.exe" (
if EXIST "!temppath!reg.exe" (
if EXIST "!temppath!where.exe" (
2020-07-03 16:05:41 +02:00
set /a found=1
2020-07-03 15:36:27 +02:00
set "ComSpec=!temppath!cmd.exe"
)
)
)
)
)
)
goto :EOF
:updatepath
set "spath="
set "upath="
2020-07-03 15:36:27 +02:00
for /f "USEBACKQ tokens=2* delims= " %%i in (`!syspath!reg.exe query "HKCU\Environment" /v "Path" 2^> nul`) do ( if not "%%j" == "" set "upath=%%j" )
for /f "USEBACKQ tokens=2* delims= " %%i in (`!syspath!reg.exe query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^> nul`) do ( if not "%%j" == "" set "spath=%%j" )
2020-04-02 02:40:50 +02:00
if not "%spath%" == "" (
REM We got something in the system path
2020-04-02 02:40:50 +02:00
set "PATH=%spath%"
if not "!upath!" == "" (
REM We also have something in the user path
2020-04-02 02:40:50 +02:00
set "PATH=%PATH%;%upath%"
)
2020-04-02 02:40:50 +02:00
) else if not "%upath%" == "" (
set "PATH=%upath%"
)
REM Remove double semicolons from the adjusted PATH
call :undouble "PATH" ";"
goto :EOF
2020-07-08 19:23:14 +02:00
:undouble <string_name> <character>
2020-04-02 02:40:50 +02:00
REM Helper function to strip doubles of a single character out of a string recursively
set "string_name=%~1"
set "character=%~2"
set "check=!%string_name%:%character%%character%=%character%!"
if not "!check!" == "!%~1!" (
set "!string_name!=!check!"
call :undouble "%~1" "%~2"
)
goto :EOF
2019-03-14 18:47:40 +01:00
:checkpy
call :updatepath
2020-07-03 15:36:27 +02:00
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe python 2^> nul`) do ( call :checkpyversion "%%x" "py2v" "py2path" "py3v" "py3path" )
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe python3 2^> nul`) do ( call :checkpyversion "%%x" "py2v" "py2path" "py3v" "py3path" )
2020-07-15 22:54:56 +02:00
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe py 2^> nul`) do ( call :checkpylauncher "%%x" "py2v" "py2path" "py3v" "py3path" )
2019-09-15 05:31:23 +02:00
set "targetpy=3"
if /i "!use_py3!" == "FALSE" (
set "targetpy=2"
set "pypath=!py2path!"
) else if /i "!use_py3!" == "FORCE" (
set "pypath=!py3path!"
) else if /i "!use_py3!" == "TRUE" (
set "pypath=!py3path!"
if "!pypath!" == "" set "pypath=!py2path!"
)
if not "!pypath!" == "" (
goto runscript
)
if "!pypath!" == "" (
2019-03-14 18:47:40 +01:00
if %tried% lss 1 (
2019-03-14 19:09:32 +01:00
if /i "!toask!"=="yes" (
REM Better ask permission first
goto askinstall
) else (
goto installpy
)
2019-03-14 18:47:40 +01:00
) else (
cls
echo ### ###
echo # Warning #
echo ### ###
2019-09-15 05:31:23 +02:00
echo.
2019-03-14 18:47:40 +01:00
REM Couldn't install for whatever reason - give the error message
echo Python is not installed or not found in your PATH var.
echo Please install it from https://www.python.org/downloads/windows/
echo.
echo Make sure you check the box labeled:
echo.
echo "Add Python X.X to PATH"
echo.
echo Where X.X is the py version you're installing.
echo.
echo Press [enter] to quit.
pause > nul
exit /b
)
)
goto runscript
2020-07-15 22:54:56 +02:00
:checkpylauncher <path> <py2v> <py2path> <py3v> <py3path>
REM Attempt to check the latest python 2 and 3 versions via the py launcher
for /f "USEBACKQ tokens=*" %%x in (`%~1 -2 -c "import sys; print(sys.executable)" 2^> nul`) do ( call :checkpyversion "%%x" "%~2" "%~3" "%~4" "%~5" )
for /f "USEBACKQ tokens=*" %%x in (`%~1 -3 -c "import sys; print(sys.executable)" 2^> nul`) do ( call :checkpyversion "%%x" "%~2" "%~3" "%~4" "%~5" )
goto :EOF
2020-07-08 19:23:14 +02:00
:checkpyversion <path> <py2v> <py2path> <py3v> <py3path>
2019-09-15 05:31:23 +02:00
set "version="&for /f "tokens=2* USEBACKQ delims= " %%a in (`"%~1" -V 2^>^&1`) do (
REM Ensure we have a version number
call :isnumber "%%a"
if not "!errorlevel!" == "0" goto :EOF
set "version=%%a"
)
if not defined version goto :EOF
if "!version:~0,1!" == "2" (
REM Python 2
call :comparepyversion "!version!" "!%~2!"
if "!errorlevel!" == "1" (
set "%~2=!version!"
set "%~3=%~1"
)
) else (
REM Python 3
call :comparepyversion "!version!" "!%~4!"
if "!errorlevel!" == "1" (
set "%~4=!version!"
set "%~5=%~1"
)
)
goto :EOF
2020-07-08 19:23:14 +02:00
:isnumber <check_value>
2019-09-15 05:31:23 +02:00
set "var="&for /f "delims=0123456789." %%i in ("%~1") do set var=%%i
if defined var (exit /b 1)
exit /b 0
2020-07-08 19:23:14 +02:00
:comparepyversion <version1> <version2> <return>
2019-09-15 05:31:23 +02:00
REM Exits with status 0 if equal, 1 if v1 gtr v2, 2 if v1 lss v2
for /f "tokens=1,2,3 delims=." %%a in ("%~1") do (
set a1=%%a
set a2=%%b
set a3=%%c
)
for /f "tokens=1,2,3 delims=." %%a in ("%~2") do (
set b1=%%a
set b2=%%b
set b3=%%c
)
if not defined a1 set a1=0
if not defined a2 set a2=0
if not defined a3 set a3=0
if not defined b1 set b1=0
if not defined b2 set b2=0
if not defined b3 set b3=0
if %a1% gtr %b1% exit /b 1
if %a1% lss %b1% exit /b 2
if %a2% gtr %b2% exit /b 1
if %a2% lss %b2% exit /b 2
if %a3% gtr %b3% exit /b 1
if %a3% lss %b3% exit /b 2
exit /b 0
2019-03-14 19:09:32 +01:00
:askinstall
cls
echo ### ###
echo # Python Not Found #
echo ### ###
echo.
2019-09-15 05:31:23 +02:00
echo Python !targetpy! was not found on the system or in the PATH var.
2019-03-14 19:09:32 +01:00
echo.
set /p "menu=Would you like to install it now? [y/n]: "
if /i "!menu!"=="y" (
REM We got the OK - install it
goto installpy
) else if "!menu!"=="n" (
REM No OK here...
set /a tried=%tried%+1
goto checkpy
)
REM Incorrect answer - go back
goto askinstall
2019-03-14 18:47:40 +01:00
:installpy
REM This will attempt to download and install python
REM First we get the html for the python downloads page for Windows
set /a tried=%tried%+1
cls
echo ### ###
echo # Installing Python #
echo ### ###
echo.
echo Gathering info from https://www.python.org/downloads/windows/...
2019-03-30 04:54:23 +01:00
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('https://www.python.org/downloads/windows/','%TEMP%\pyurl.txt')"
2019-03-14 18:47:40 +01:00
if not exist "%TEMP%\pyurl.txt" (
goto checkpy
)
echo Parsing for latest...
pushd "%TEMP%"
:: Version detection code slimmed by LussacZheng (https://github.com/corpnewt/gibMacOS/issues/20)
2019-09-15 05:31:23 +02:00
for /f "tokens=9 delims=< " %%x in ('findstr /i /c:"Latest Python !targetpy! Release" pyurl.txt') do ( set "release=%%x" )
2019-03-14 18:47:40 +01:00
popd
echo Found Python !release! - Downloading...
REM Let's delete our txt file now - we no longer need it
del "%TEMP%\pyurl.txt"
REM At this point - we should have the version number.
REM We can build the url like so: "https://www.python.org/ftp/python/[version]/python-[version]-amd64.exe"
set "url=https://www.python.org/ftp/python/!release!/python-!release!-amd64.exe"
2019-09-15 05:31:23 +02:00
set "pytype=exe"
if "!targetpy!" == "2" (
set "url=https://www.python.org/ftp/python/!release!/python-!release!.amd64.msi"
set "pytype=msi"
)
2019-03-14 18:47:40 +01:00
REM Now we download it with our slick powershell command
2019-09-15 05:31:23 +02:00
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('!url!','%TEMP%\pyinstall.!pytype!')"
2019-03-14 18:47:40 +01:00
REM If it doesn't exist - we bail
2019-09-15 05:31:23 +02:00
if not exist "%TEMP%\pyinstall.!pytype!" (
2019-03-14 18:47:40 +01:00
goto checkpy
)
REM It should exist at this point - let's run it to install silently
echo Installing...
pushd "%TEMP%"
2019-09-15 05:31:23 +02:00
if /i "!pytype!" == "exe" (
echo pyinstall.exe /quiet PrependPath=1 Include_test=0 Shortcuts=0 Include_launcher=0
pyinstall.exe /quiet PrependPath=1 Include_test=0 Shortcuts=0 Include_launcher=0
) else (
set "foldername=!release:.=!"
echo msiexec /i pyinstall.msi /qb ADDLOCAL=ALL TARGETDIR="%LocalAppData%\Programs\Python\Python!foldername:~0,2!"
msiexec /i pyinstall.msi /qb ADDLOCAL=ALL TARGETDIR="%LocalAppData%\Programs\Python\Python!foldername:~0,2!"
)
2019-03-14 18:47:40 +01:00
popd
2019-09-15 05:31:23 +02:00
echo Installer finished with %ERRORLEVEL% status.
2019-03-14 18:47:40 +01:00
REM Now we should be able to delete the installer and check for py again
2019-09-15 05:31:23 +02:00
del "%TEMP%\pyinstall.!pytype!"
2019-03-14 18:47:40 +01:00
REM If it worked, then we should have python in our PATH
REM this does not get updated right away though - let's try
REM manually updating the local PATH var
call :updatepath
2019-03-14 18:47:40 +01:00
goto checkpy
exit /b
2018-09-26 06:16:18 +02:00
2019-03-14 18:47:40 +01:00
:runscript
2018-09-26 06:16:18 +02:00
REM Python found
2019-03-14 19:15:52 +01:00
cls
2019-06-14 18:28:39 +02:00
set "args=%*"
set "args=!args:"=!"
if "!args!"=="" (
2019-09-15 05:31:23 +02:00
"!pypath!" "!thisDir!!script_name!"
2018-09-26 06:16:18 +02:00
) else (
2019-09-15 05:31:23 +02:00
"!pypath!" "!thisDir!!script_name!" %*
2019-02-21 20:29:15 +01:00
)
2020-07-05 18:44:57 +02:00
if /i "!pause_on_error!" == "yes" (
if not "%ERRORLEVEL%" == "0" (
echo.
echo Script exited with error code: %ERRORLEVEL%
echo.
echo Press [enter] to exit...
pause > nul
)
)
2019-03-14 18:47:40 +01:00
goto :EOF