Compare commits

...

16 Commits

Author SHA1 Message Date
Andrew Lee 111a43174e
Merge 5629ebe7bb into 0749880ad1 2024-03-29 12:38:04 +03:00
CorpNewt 0749880ad1
Update gibMacOS.command 2024-03-23 12:34:48 -05:00
CorpNewt f0db386238
Update BuildmacOSInstallApp.command 2024-03-23 12:34:28 -05:00
CorpNewt a86022adb7 Line ending woes 2024-03-13 09:28:01 -05:00
CorpNewt 12de8f78a3
Updates for python.org gzip compression 2024-03-13 04:18:50 -05:00
CorpNewt 2a60cda8dd
Updates for python.org gzip compression 2024-03-13 04:18:42 -05:00
Andrew Lee 5629ebe7bb
Merge branch 'master' of https://github.com/corpnewt/gibMacOS 2021-04-23 21:16:38 -04:00
Andrew Lee 190f445388
Merge branch 'master' of https://github.com/corpnewt/gibMacOS into master 2020-10-29 23:35:26 -04:00
Andrew Lee e1f207fea4
Updated fork 2020-06-23 17:28:10 -04:00
Andrew Lee 73cd1f80ff
Updated fork 2020-05-22 20:42:18 -04:00
Alee 57c34579af
Merge pull request #1 from corpnewt/master
Update fork
2020-05-01 23:54:23 -04:00
Andrew Lee 8a055c2ffc
Changed the name to LinuxFlash 2020-04-28 17:59:10 -04:00
Andrew Lee 77af7bb4e5
Capitalized the name 2020-04-28 16:51:34 -04:00
Andrew Lee 6d7b7fd31b
Added continue at risk option 2020-04-28 16:40:54 -04:00
Andrew Lee ac34e09d12
Set finalflash.sh to be executable 2020-04-27 20:01:01 -04:00
Andrew Lee 0f380a4db1
Added FinalFlash 2020-04-27 19:57:11 -04:00
5 changed files with 1003 additions and 782 deletions

View File

@ -3,7 +3,7 @@
# Get the curent directory, the script name
# and the script name with "py" substituted for the extension.
args=( "$@" )
dir="${0%/*}"
dir="$(cd -- "$(dirname "$0")" >/dev/null 2>&1; pwd -P)"
script="${0##*/}"
target="${script%.*}.py"

207
LinuxFlash.sh Executable file
View File

@ -0,0 +1,207 @@
#!/bin/bash
# Autor: Broly
# License: GNU General Public License v3.0
# https://www.gnu.org/licenses/gpl-3.0.txt
# This script is inteded to create a opencore usb-installer on linux just like
#'Makeinstall.py" does on windows there for it should be executerd
# from /gibMacOS-master/ directory.
# dependency gibmacos https://github.com/corpnewt/gibMacOS
RED="\033[1;31m\e[3m"
NOCOLOR="\e[0m\033[0m"
YELLOW="\033[01;33m\e[3m"
set -e
# Checking for root Identifying distro pkg-manager and installing dependencies.
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be executed as root!${NOCOLOR}"
exit 1
fi
echo -e "\e[3mWe need to install some important tools to proceed!\e[0m"
sleep 3s
declare -A osInfo;
osInfo[/etc/debian_version]="apt install -y"
osInfo[/etc/alpine-release]="apk --update add"
osInfo[/etc/centos-release]="yum install -y"
osInfo[/etc/fedora-release]="dnf install -y"
osInfo[/etc/arch-release]="pacman -S --noconfirm"
for f in ${!osInfo[@]}
do
if [[ -f $f ]];then
package_manager=${osInfo[$f]}
fi
done
echo -e "\e[3mInstalling Depencencies...\e[0m"
package="wget curl p7zip"
package1="wget curl p7zip"
package2="wget curl p7zip-full"
if [ "${package_manager}" = "pacman -S --noconfirm" ]; then
${package_manager} ${package1}
elif [ "${package_manager}" = "apt install -y" ]; then
${package_manager} ${package2}
elif [ "${package_manager}" = "yum install -y" ]; then
${package_manager} ${package1}
elif [ "${package_manager}" = "dnf install -y" ]; then
${package_manager} ${package}
else
echo -e "${YELLOW}Warning: Your distro is not supported!${NOCOLOR}"
echo -e "You must install the following tools: wget, curl and p7zip"
while true
do
read -r -p "Want to continue at risk? (y/n) " input
case $input in
[yY])
break
;;
[nN])
exit 1
;;
*)
echo "Invalid input..."
;;
esac
done
fi
# Simple menu to select the Downloaded version of macOS only usefull if you download
# multiple versions.
cd "$(dirname "$(find ./ -name "publicrelease")")"
cd publicrelease
echo -e "${YELLOW}Please select the downloaded macOS image!${NOCOLOR}"
if select d in */; do test -n "$d" && break; echo -e "${RED}>>> Invalid Selection !${NOCOLOR}"; done
then
# checking if we have recovery.pkg to proceed.
cd "$d"
FILE=(RecoveryHDMetaDmg.pkg)
FILE1=(*.RecoveryHDUpdate.pkg)
if [ -f "$FILE" ]; then
echo "Using $FILE"
7z e -txar $FILE *.dmg
7z e *.dmg */Base*.dmg
7z e -tdmg Base*.dmg *.hfs
mv *.hfs base.hfs
sleep 3s
elif [ -f "$FILE1" ]; then
mv $FILE1 $FILE
7z e -txar $FILE *.dmg
7z e *.dmg */Base*.dmg
7z e -tdmg Base*.dmg *.hfs
mv *.hfs base.hfs
sleep 3s
else
echo -e "${YELLOW}Please Download macOS with gibmacos!${NOCOLOR}"
exit 1
fi
fi
# Print disk devices
# Read command output line by line into array ${lines [@]}
# Bash 3.x: use the following instead:
# IFS=$'\n' read -d '' -ra lines < <(lsblk --nodeps -no name,size | grep "sd")
readarray -t lines < <(lsblk --nodeps -no name,size | grep "sd")
# Prompt the user to select the drive.
echo -e "${RED}WARNING: THE SELECTED DRIVE WILL BE FORMATED !!!${NOCOLOR}"
echo -e "${YELLOW}Please select the usb-drive!${NOCOLOR}"
select choice in "${lines[@]}"; do
[[ -n $choice ]] || { echo -e "${RED}>>> Invalid Selection !${NOCOLOR}" >&2; continue; }
break # valid choice was made; exit prompt.
done
# Split the chosen line into ID and serial number.
read -r id sn unused <<<"$choice"
# Move the recovery to /tmp delete everything in the current directory then bring it back.
teleport(){
if
mv $FILE /tmp/
sleep 2s
then
rm -rf *.*
mv /tmp/$FILE .
sleep 2s
else
exit 1
fi
}
# Here we partition the drive and dd the raw image to it.
partformat(){
if
umount $(echo /dev/$id?*) > /dev/null 2>&1 || :
sleep 3s
sgdisk --zap-all /dev/$id > /dev/null 2>&1
sgdisk /dev/$id --new=0:0:+300MiB -t 0:ef00
partprobe $(echo /dev/$id?*)
sgdisk -e /dev/$id --new=0:0:+7000MiB -t 0:af00
partprobe $(echo /dev/$id?*)
sleep 3s
echo -e "\e[3mCopying image to usb-drive!\e[0m"
dd bs=8M if="$PWD/base.hfs" of=$(echo /dev/$id)2 status=progress oflag=sync
teleport
then
umount $(echo /dev/$id?*) > /dev/null 2>&1 || :
sleep 3s
else
exit 1
fi
}
while true; do
read -p "$(echo -e ${YELLOW}"Drive ($id) will be erased, do you wish to continue (y/n)? "${NOCOLOR})" yn
case $yn in
[Yy]* ) partformat; break;;
[Nn]* ) teleport; exit;;
* ) echo -e "${YELLOW}Please answer yes or no."${NOCOLOR};;
esac
done
# Format the EFI partition for opencore
# and mount it in the /mnt.
if
mkfs.fat -F32 -n EFI $(echo /dev/$id)1
then
mount -t vfat $(echo /dev/$id)1 /mnt/ -o rw,umask=000; sleep 3s
else
exit 1
fi
# Install opencore.
echo -e "\e[3mInstalling OpenCore!!\e[0m"
sleep 3s
# OpenCore Downloader fuction.
if
curl "https://api.github.com/repos/acidanthera/OpenCorePkg/releases/latest" \
| grep -i browser_download_url \
| grep RELEASE.zip \
| cut -d'"' -f4 \
| wget -qi -
then
7z x *RELEASE.zip -o/mnt/
else
exit 1
fi
sleep 5s
chmod +x /mnt/
rm -rf *RELEASE.zip
umount $(echo /dev/$id)1
mount -t vfat $(echo /dev/$id)1 /mnt/ -o rw,umask=000
sleep 3s
echo -e "\e[3mInstallation finished, open /mnt and edit oc for your machine!!\e[0m"

View File

@ -1,390 +1,397 @@
@echo off
REM Get our local path before delayed expansion - allows ! in path
set "thisDir=%~dp0"
setlocal enableDelayedExpansion
REM Setup initial vars
set "script_name="
set /a tried=0
set "toask=yes"
set "pause_on_error=yes"
set "py2v="
set "py2path="
set "py3v="
set "py3path="
set "pypath="
set "targetpy=3"
REM use_py3:
REM TRUE = Use if found, use py2 otherwise
REM FALSE = Use py2
REM FORCE = Use py3
set "use_py3=TRUE"
REM We'll parse if the first argument passed is
REM --install-python and if so, we'll just install
set "just_installing=FALSE"
REM Get the system32 (or equivalent) path
call :getsyspath "syspath"
REM Make sure the syspath exists
if "!syspath!" == "" (
if exist "%SYSTEMROOT%\system32\cmd.exe" (
if exist "%SYSTEMROOT%\system32\reg.exe" (
if exist "%SYSTEMROOT%\system32\where.exe" (
REM Fall back on the default path if it exists
set "ComSpec=%SYSTEMROOT%\system32\cmd.exe"
set "syspath=%SYSTEMROOT%\system32\"
)
)
)
if "!syspath!" == "" (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
echo Could not locate cmd.exe, reg.exe, or where.exe
echo.
echo Please ensure your ComSpec environment variable is properly configured and
echo points directly to cmd.exe, then try again.
echo.
echo Current CompSpec Value: "%ComSpec%"
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
)
if "%~1" == "--install-python" (
set "just_installing=TRUE"
goto installpy
)
goto checkscript
:checkscript
REM Check for our script first
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"
)
)
if not exist "!thisDir!\!script_name!" (
echo Could not find !looking_for!.
echo Please make sure to run this script from the same directory
echo as !looking_for!.
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
goto checkpy
:checkpy
call :updatepath
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" )
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe py 2^> nul`) do ( call :checkpylauncher "%%x" "py2v" "py2path" "py3v" "py3path" )
REM Walk our returns to see if we need to install
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 !tried! lss 1 (
if /i "!toask!"=="yes" (
REM Better ask permission first
goto askinstall
) else (
goto installpy
)
) else (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
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 1
)
goto runscript
: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
:checkpyversion <path> <py2v> <py2path> <py3v> <py3path>
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
:isnumber <check_value>
set "var="&for /f "delims=0123456789." %%i in ("%~1") do set var=%%i
if defined var (exit /b 1)
exit /b 0
:comparepyversion <version1> <version2> <return>
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
:askinstall
cls
echo ### ###
echo # Python Not Found #
echo ### ###
echo.
echo Python !targetpy! was not found on the system or in the PATH var.
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
: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/...
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('https://www.python.org/downloads/windows/','%TEMP%\pyurl.txt')"
if not exist "%TEMP%\pyurl.txt" (
if /i "!just_installing!" == "TRUE" (
echo Failed to get info
exit /b 1
) else (
goto checkpy
)
)
echo Parsing for latest...
pushd "%TEMP%"
:: Version detection code slimmed by LussacZheng (https://github.com/corpnewt/gibMacOS/issues/20)
for /f "tokens=9 delims=< " %%x in ('findstr /i /c:"Latest Python !targetpy! Release" pyurl.txt') do ( set "release=%%x" )
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"
set "pytype=exe"
if "!targetpy!" == "2" (
set "url=https://www.python.org/ftp/python/!release!/python-!release!.amd64.msi"
set "pytype=msi"
)
REM Now we download it with our slick powershell command
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('!url!','%TEMP%\pyinstall.!pytype!')"
REM If it doesn't exist - we bail
if not exist "%TEMP%\pyinstall.!pytype!" (
if /i "!just_installing!" == "TRUE" (
echo Failed to download installer
exit /b 1
) else (
goto checkpy
)
)
REM It should exist at this point - let's run it to install silently
echo Installing...
pushd "%TEMP%"
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!"
)
popd
echo Installer finished with %ERRORLEVEL% status.
REM Now we should be able to delete the installer and check for py again
del "%TEMP%\pyinstall.!pytype!"
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
if /i "!just_installing!" == "TRUE" (
echo.
echo Done.
) else (
goto checkpy
)
exit /b
:runscript
REM Python found
cls
set "args=%*"
set "args=!args:"=!"
if "!args!"=="" (
"!pypath!" "!thisDir!!script_name!"
) else (
"!pypath!" "!thisDir!!script_name!" %*
)
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
)
)
goto :EOF
:undouble <string_name> <string_value> <character>
REM Helper function to strip doubles of a single character out of a string recursively
set "string_value=%~2"
:undouble_continue
set "check=!string_value:%~3%~3=%~3!"
if not "!check!" == "!string_value!" (
set "string_value=!check!"
goto :undouble_continue
)
set "%~1=!check!"
goto :EOF
:updatepath
set "spath="
set "upath="
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" )
if not "%spath%" == "" (
REM We got something in the system path
set "PATH=%spath%"
if not "%upath%" == "" (
REM We also have something in the user path
set "PATH=%PATH%;%upath%"
)
) else if not "%upath%" == "" (
set "PATH=%upath%"
)
REM Remove double semicolons from the adjusted PATH
call :undouble "PATH" "%PATH%" ";"
goto :EOF
:getsyspath <variable_name>
REM Helper method to return a valid path to cmd.exe, reg.exe, and where.exe by
REM walking the ComSpec var - will also repair it in memory if need be
REM Strip double semi-colons
call :undouble "temppath" "%ComSpec%" ";"
REM Dirty hack to leverage the "line feed" approach - there are some odd side
REM effects with this. Do not use this variable name in comments near this
REM line - as it seems to behave erradically.
(set LF=^
%=this line is empty=%
)
REM Replace instances of semi-colons with a line feed and wrap
REM in parenthesis to work around some strange batch behavior
set "testpath=%temppath:;=!LF!%"
REM Let's walk each path and test if cmd.exe, reg.exe, and where.exe exist there
set /a found=0
for /f "tokens=* delims=" %%i in ("!testpath!") do (
REM Only continue if we haven't found it yet
if not "%%i" == "" (
if !found! lss 1 (
set "checkpath=%%i"
REM Remove "cmd.exe" from the end if it exists
if /i "!checkpath:~-7!" == "cmd.exe" (
set "checkpath=!checkpath:~0,-7!"
)
REM Pad the end with a backslash if needed
if not "!checkpath:~-1!" == "\" (
set "checkpath=!checkpath!\"
)
REM Let's see if cmd, reg, and where exist there - and set it if so
if EXIST "!checkpath!cmd.exe" (
if EXIST "!checkpath!reg.exe" (
if EXIST "!checkpath!where.exe" (
set /a found=1
set "ComSpec=!checkpath!cmd.exe"
set "%~1=!checkpath!"
)
)
)
)
)
)
goto :EOF
@echo off
REM Get our local path before delayed expansion - allows ! in path
set "thisDir=%~dp0"
setlocal enableDelayedExpansion
REM Setup initial vars
set "script_name="
set /a tried=0
set "toask=yes"
set "pause_on_error=yes"
set "py2v="
set "py2path="
set "py3v="
set "py3path="
set "pypath="
set "targetpy=3"
REM use_py3:
REM TRUE = Use if found, use py2 otherwise
REM FALSE = Use py2
REM FORCE = Use py3
set "use_py3=TRUE"
REM We'll parse if the first argument passed is
REM --install-python and if so, we'll just install
set "just_installing=FALSE"
REM Get the system32 (or equivalent) path
call :getsyspath "syspath"
REM Make sure the syspath exists
if "!syspath!" == "" (
if exist "%SYSTEMROOT%\system32\cmd.exe" (
if exist "%SYSTEMROOT%\system32\reg.exe" (
if exist "%SYSTEMROOT%\system32\where.exe" (
REM Fall back on the default path if it exists
set "ComSpec=%SYSTEMROOT%\system32\cmd.exe"
set "syspath=%SYSTEMROOT%\system32\"
)
)
)
if "!syspath!" == "" (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
echo Could not locate cmd.exe, reg.exe, or where.exe
echo.
echo Please ensure your ComSpec environment variable is properly configured and
echo points directly to cmd.exe, then try again.
echo.
echo Current CompSpec Value: "%ComSpec%"
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
)
if "%~1" == "--install-python" (
set "just_installing=TRUE"
goto installpy
)
goto checkscript
:checkscript
REM Check for our script first
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"
)
)
if not exist "!thisDir!\!script_name!" (
echo Could not find !looking_for!.
echo Please make sure to run this script from the same directory
echo as !looking_for!.
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
goto checkpy
:checkpy
call :updatepath
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" )
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe py 2^> nul`) do ( call :checkpylauncher "%%x" "py2v" "py2path" "py3v" "py3path" )
REM Walk our returns to see if we need to install
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 !tried! lss 1 (
if /i "!toask!"=="yes" (
REM Better ask permission first
goto askinstall
) else (
goto installpy
)
) else (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
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 1
)
goto runscript
: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
:checkpyversion <path> <py2v> <py2path> <py3v> <py3path>
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
:isnumber <check_value>
set "var="&for /f "delims=0123456789." %%i in ("%~1") do set var=%%i
if defined var (exit /b 1)
exit /b 0
:comparepyversion <version1> <version2> <return>
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
:askinstall
cls
echo ### ###
echo # Python Not Found #
echo ### ###
echo.
echo Python !targetpy! was not found on the system or in the PATH var.
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
: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/...
powershell -command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;(new-object System.Net.WebClient).DownloadFile('https://www.python.org/downloads/windows/','%TEMP%\pyurl.txt')"
REM Extract it if it's gzip compressed
powershell -command "$infile='%TEMP%\pyurl.txt';$outfile='%TEMP%\pyurl.temp';try{$input=New-Object System.IO.FileStream $infile,([IO.FileMode]::Open),([IO.FileAccess]::Read),([IO.FileShare]::Read);$output=New-Object System.IO.FileStream $outfile,([IO.FileMode]::Create),([IO.FileAccess]::Write),([IO.FileShare]::None);$gzipStream=New-Object System.IO.Compression.GzipStream $input,([IO.Compression.CompressionMode]::Decompress);$buffer=New-Object byte[](1024);while($true){$read=$gzipstream.Read($buffer,0,1024);if($read -le 0){break};$output.Write($buffer,0,$read)};$gzipStream.Close();$output.Close();$input.Close();Move-Item -Path $outfile -Destination $infile -Force}catch{}"
if not exist "%TEMP%\pyurl.txt" (
if /i "!just_installing!" == "TRUE" (
echo Failed to get info
exit /b 1
) else (
goto checkpy
)
)
echo Parsing for latest...
pushd "%TEMP%"
:: Version detection code slimmed by LussacZheng (https://github.com/corpnewt/gibMacOS/issues/20)
for /f "tokens=9 delims=< " %%x in ('findstr /i /c:"Latest Python !targetpy! Release" pyurl.txt') do ( set "release=%%x" )
popd
if "!release!" == "" (
if /i "!just_installing!" == "TRUE" (
echo Failed to get python version
exit /b 1
) else (
goto checkpy
)
)
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"
set "pytype=exe"
if "!targetpy!" == "2" (
set "url=https://www.python.org/ftp/python/!release!/python-!release!.amd64.msi"
set "pytype=msi"
)
REM Now we download it with our slick powershell command
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('!url!','%TEMP%\pyinstall.!pytype!')"
REM If it doesn't exist - we bail
if not exist "%TEMP%\pyinstall.!pytype!" (
if /i "!just_installing!" == "TRUE" (
echo Failed to download installer
exit /b 1
) else (
goto checkpy
)
)
REM It should exist at this point - let's run it to install silently
echo Installing...
pushd "%TEMP%"
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!"
)
popd
echo Installer finished with %ERRORLEVEL% status.
REM Now we should be able to delete the installer and check for py again
del "%TEMP%\pyinstall.!pytype!"
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
if /i "!just_installing!" == "TRUE" (
echo.
echo Done.
) else (
goto checkpy
)
exit /b
:runscript
REM Python found
cls
set "args=%*"
set "args=!args:"=!"
if "!args!"=="" (
"!pypath!" "!thisDir!!script_name!"
) else (
"!pypath!" "!thisDir!!script_name!" %*
)
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
)
)
goto :EOF
:undouble <string_name> <string_value> <character>
REM Helper function to strip doubles of a single character out of a string recursively
set "string_value=%~2"
:undouble_continue
set "check=!string_value:%~3%~3=%~3!"
if not "!check!" == "!string_value!" (
set "string_value=!check!"
goto :undouble_continue
)
set "%~1=!check!"
goto :EOF
:updatepath
set "spath="
set "upath="
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" )
if not "%spath%" == "" (
REM We got something in the system path
set "PATH=%spath%"
if not "%upath%" == "" (
REM We also have something in the user path
set "PATH=%PATH%;%upath%"
)
) else if not "%upath%" == "" (
set "PATH=%upath%"
)
REM Remove double semicolons from the adjusted PATH
call :undouble "PATH" "%PATH%" ";"
goto :EOF
:getsyspath <variable_name>
REM Helper method to return a valid path to cmd.exe, reg.exe, and where.exe by
REM walking the ComSpec var - will also repair it in memory if need be
REM Strip double semi-colons
call :undouble "temppath" "%ComSpec%" ";"
REM Dirty hack to leverage the "line feed" approach - there are some odd side
REM effects with this. Do not use this variable name in comments near this
REM line - as it seems to behave erradically.
(set LF=^
%=this line is empty=%
)
REM Replace instances of semi-colons with a line feed and wrap
REM in parenthesis to work around some strange batch behavior
set "testpath=%temppath:;=!LF!%"
REM Let's walk each path and test if cmd.exe, reg.exe, and where.exe exist there
set /a found=0
for /f "tokens=* delims=" %%i in ("!testpath!") do (
REM Only continue if we haven't found it yet
if not "%%i" == "" (
if !found! lss 1 (
set "checkpath=%%i"
REM Remove "cmd.exe" from the end if it exists
if /i "!checkpath:~-7!" == "cmd.exe" (
set "checkpath=!checkpath:~0,-7!"
)
REM Pad the end with a backslash if needed
if not "!checkpath:~-1!" == "\" (
set "checkpath=!checkpath!\"
)
REM Let's see if cmd, reg, and where exist there - and set it if so
if EXIST "!checkpath!cmd.exe" (
if EXIST "!checkpath!reg.exe" (
if EXIST "!checkpath!where.exe" (
set /a found=1
set "ComSpec=!checkpath!cmd.exe"
set "%~1=!checkpath!"
)
)
)
)
)
)
goto :EOF

View File

@ -1,390 +1,397 @@
@echo off
REM Get our local path before delayed expansion - allows ! in path
set "thisDir=%~dp0"
setlocal enableDelayedExpansion
REM Setup initial vars
set "script_name="
set /a tried=0
set "toask=yes"
set "pause_on_error=yes"
set "py2v="
set "py2path="
set "py3v="
set "py3path="
set "pypath="
set "targetpy=3"
REM use_py3:
REM TRUE = Use if found, use py2 otherwise
REM FALSE = Use py2
REM FORCE = Use py3
set "use_py3=TRUE"
REM We'll parse if the first argument passed is
REM --install-python and if so, we'll just install
set "just_installing=FALSE"
REM Get the system32 (or equivalent) path
call :getsyspath "syspath"
REM Make sure the syspath exists
if "!syspath!" == "" (
if exist "%SYSTEMROOT%\system32\cmd.exe" (
if exist "%SYSTEMROOT%\system32\reg.exe" (
if exist "%SYSTEMROOT%\system32\where.exe" (
REM Fall back on the default path if it exists
set "ComSpec=%SYSTEMROOT%\system32\cmd.exe"
set "syspath=%SYSTEMROOT%\system32\"
)
)
)
if "!syspath!" == "" (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
echo Could not locate cmd.exe, reg.exe, or where.exe
echo.
echo Please ensure your ComSpec environment variable is properly configured and
echo points directly to cmd.exe, then try again.
echo.
echo Current CompSpec Value: "%ComSpec%"
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
)
if "%~1" == "--install-python" (
set "just_installing=TRUE"
goto installpy
)
goto checkscript
:checkscript
REM Check for our script first
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"
)
)
if not exist "!thisDir!\!script_name!" (
echo Could not find !looking_for!.
echo Please make sure to run this script from the same directory
echo as !looking_for!.
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
goto checkpy
:checkpy
call :updatepath
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" )
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe py 2^> nul`) do ( call :checkpylauncher "%%x" "py2v" "py2path" "py3v" "py3path" )
REM Walk our returns to see if we need to install
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 !tried! lss 1 (
if /i "!toask!"=="yes" (
REM Better ask permission first
goto askinstall
) else (
goto installpy
)
) else (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
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 1
)
goto runscript
: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
:checkpyversion <path> <py2v> <py2path> <py3v> <py3path>
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
:isnumber <check_value>
set "var="&for /f "delims=0123456789." %%i in ("%~1") do set var=%%i
if defined var (exit /b 1)
exit /b 0
:comparepyversion <version1> <version2> <return>
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
:askinstall
cls
echo ### ###
echo # Python Not Found #
echo ### ###
echo.
echo Python !targetpy! was not found on the system or in the PATH var.
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
: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/...
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('https://www.python.org/downloads/windows/','%TEMP%\pyurl.txt')"
if not exist "%TEMP%\pyurl.txt" (
if /i "!just_installing!" == "TRUE" (
echo Failed to get info
exit /b 1
) else (
goto checkpy
)
)
echo Parsing for latest...
pushd "%TEMP%"
:: Version detection code slimmed by LussacZheng (https://github.com/corpnewt/gibMacOS/issues/20)
for /f "tokens=9 delims=< " %%x in ('findstr /i /c:"Latest Python !targetpy! Release" pyurl.txt') do ( set "release=%%x" )
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"
set "pytype=exe"
if "!targetpy!" == "2" (
set "url=https://www.python.org/ftp/python/!release!/python-!release!.amd64.msi"
set "pytype=msi"
)
REM Now we download it with our slick powershell command
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('!url!','%TEMP%\pyinstall.!pytype!')"
REM If it doesn't exist - we bail
if not exist "%TEMP%\pyinstall.!pytype!" (
if /i "!just_installing!" == "TRUE" (
echo Failed to download installer
exit /b 1
) else (
goto checkpy
)
)
REM It should exist at this point - let's run it to install silently
echo Installing...
pushd "%TEMP%"
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!"
)
popd
echo Installer finished with %ERRORLEVEL% status.
REM Now we should be able to delete the installer and check for py again
del "%TEMP%\pyinstall.!pytype!"
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
if /i "!just_installing!" == "TRUE" (
echo.
echo Done.
) else (
goto checkpy
)
exit /b
:runscript
REM Python found
cls
set "args=%*"
set "args=!args:"=!"
if "!args!"=="" (
"!pypath!" "!thisDir!!script_name!"
) else (
"!pypath!" "!thisDir!!script_name!" %*
)
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
)
)
goto :EOF
:undouble <string_name> <string_value> <character>
REM Helper function to strip doubles of a single character out of a string recursively
set "string_value=%~2"
:undouble_continue
set "check=!string_value:%~3%~3=%~3!"
if not "!check!" == "!string_value!" (
set "string_value=!check!"
goto :undouble_continue
)
set "%~1=!check!"
goto :EOF
:updatepath
set "spath="
set "upath="
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" )
if not "%spath%" == "" (
REM We got something in the system path
set "PATH=%spath%"
if not "%upath%" == "" (
REM We also have something in the user path
set "PATH=%PATH%;%upath%"
)
) else if not "%upath%" == "" (
set "PATH=%upath%"
)
REM Remove double semicolons from the adjusted PATH
call :undouble "PATH" "%PATH%" ";"
goto :EOF
:getsyspath <variable_name>
REM Helper method to return a valid path to cmd.exe, reg.exe, and where.exe by
REM walking the ComSpec var - will also repair it in memory if need be
REM Strip double semi-colons
call :undouble "temppath" "%ComSpec%" ";"
REM Dirty hack to leverage the "line feed" approach - there are some odd side
REM effects with this. Do not use this variable name in comments near this
REM line - as it seems to behave erradically.
(set LF=^
%=this line is empty=%
)
REM Replace instances of semi-colons with a line feed and wrap
REM in parenthesis to work around some strange batch behavior
set "testpath=%temppath:;=!LF!%"
REM Let's walk each path and test if cmd.exe, reg.exe, and where.exe exist there
set /a found=0
for /f "tokens=* delims=" %%i in ("!testpath!") do (
REM Only continue if we haven't found it yet
if not "%%i" == "" (
if !found! lss 1 (
set "checkpath=%%i"
REM Remove "cmd.exe" from the end if it exists
if /i "!checkpath:~-7!" == "cmd.exe" (
set "checkpath=!checkpath:~0,-7!"
)
REM Pad the end with a backslash if needed
if not "!checkpath:~-1!" == "\" (
set "checkpath=!checkpath!\"
)
REM Let's see if cmd, reg, and where exist there - and set it if so
if EXIST "!checkpath!cmd.exe" (
if EXIST "!checkpath!reg.exe" (
if EXIST "!checkpath!where.exe" (
set /a found=1
set "ComSpec=!checkpath!cmd.exe"
set "%~1=!checkpath!"
)
)
)
)
)
)
goto :EOF
@echo off
REM Get our local path before delayed expansion - allows ! in path
set "thisDir=%~dp0"
setlocal enableDelayedExpansion
REM Setup initial vars
set "script_name="
set /a tried=0
set "toask=yes"
set "pause_on_error=yes"
set "py2v="
set "py2path="
set "py3v="
set "py3path="
set "pypath="
set "targetpy=3"
REM use_py3:
REM TRUE = Use if found, use py2 otherwise
REM FALSE = Use py2
REM FORCE = Use py3
set "use_py3=TRUE"
REM We'll parse if the first argument passed is
REM --install-python and if so, we'll just install
set "just_installing=FALSE"
REM Get the system32 (or equivalent) path
call :getsyspath "syspath"
REM Make sure the syspath exists
if "!syspath!" == "" (
if exist "%SYSTEMROOT%\system32\cmd.exe" (
if exist "%SYSTEMROOT%\system32\reg.exe" (
if exist "%SYSTEMROOT%\system32\where.exe" (
REM Fall back on the default path if it exists
set "ComSpec=%SYSTEMROOT%\system32\cmd.exe"
set "syspath=%SYSTEMROOT%\system32\"
)
)
)
if "!syspath!" == "" (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
echo Could not locate cmd.exe, reg.exe, or where.exe
echo.
echo Please ensure your ComSpec environment variable is properly configured and
echo points directly to cmd.exe, then try again.
echo.
echo Current CompSpec Value: "%ComSpec%"
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
)
if "%~1" == "--install-python" (
set "just_installing=TRUE"
goto installpy
)
goto checkscript
:checkscript
REM Check for our script first
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"
)
)
if not exist "!thisDir!\!script_name!" (
echo Could not find !looking_for!.
echo Please make sure to run this script from the same directory
echo as !looking_for!.
echo.
echo Press [enter] to quit.
pause > nul
exit /b 1
)
goto checkpy
:checkpy
call :updatepath
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" )
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe py 2^> nul`) do ( call :checkpylauncher "%%x" "py2v" "py2path" "py3v" "py3path" )
REM Walk our returns to see if we need to install
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 !tried! lss 1 (
if /i "!toask!"=="yes" (
REM Better ask permission first
goto askinstall
) else (
goto installpy
)
) else (
cls
echo ### ###
echo # Warning #
echo ### ###
echo.
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 1
)
goto runscript
: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
:checkpyversion <path> <py2v> <py2path> <py3v> <py3path>
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
:isnumber <check_value>
set "var="&for /f "delims=0123456789." %%i in ("%~1") do set var=%%i
if defined var (exit /b 1)
exit /b 0
:comparepyversion <version1> <version2> <return>
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
:askinstall
cls
echo ### ###
echo # Python Not Found #
echo ### ###
echo.
echo Python !targetpy! was not found on the system or in the PATH var.
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
: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/...
powershell -command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;(new-object System.Net.WebClient).DownloadFile('https://www.python.org/downloads/windows/','%TEMP%\pyurl.txt')"
REM Extract it if it's gzip compressed
powershell -command "$infile='%TEMP%\pyurl.txt';$outfile='%TEMP%\pyurl.temp';try{$input=New-Object System.IO.FileStream $infile,([IO.FileMode]::Open),([IO.FileAccess]::Read),([IO.FileShare]::Read);$output=New-Object System.IO.FileStream $outfile,([IO.FileMode]::Create),([IO.FileAccess]::Write),([IO.FileShare]::None);$gzipStream=New-Object System.IO.Compression.GzipStream $input,([IO.Compression.CompressionMode]::Decompress);$buffer=New-Object byte[](1024);while($true){$read=$gzipstream.Read($buffer,0,1024);if($read -le 0){break};$output.Write($buffer,0,$read)};$gzipStream.Close();$output.Close();$input.Close();Move-Item -Path $outfile -Destination $infile -Force}catch{}"
if not exist "%TEMP%\pyurl.txt" (
if /i "!just_installing!" == "TRUE" (
echo Failed to get info
exit /b 1
) else (
goto checkpy
)
)
echo Parsing for latest...
pushd "%TEMP%"
:: Version detection code slimmed by LussacZheng (https://github.com/corpnewt/gibMacOS/issues/20)
for /f "tokens=9 delims=< " %%x in ('findstr /i /c:"Latest Python !targetpy! Release" pyurl.txt') do ( set "release=%%x" )
popd
if "!release!" == "" (
if /i "!just_installing!" == "TRUE" (
echo Failed to get python version
exit /b 1
) else (
goto checkpy
)
)
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"
set "pytype=exe"
if "!targetpy!" == "2" (
set "url=https://www.python.org/ftp/python/!release!/python-!release!.amd64.msi"
set "pytype=msi"
)
REM Now we download it with our slick powershell command
powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (new-object System.Net.WebClient).DownloadFile('!url!','%TEMP%\pyinstall.!pytype!')"
REM If it doesn't exist - we bail
if not exist "%TEMP%\pyinstall.!pytype!" (
if /i "!just_installing!" == "TRUE" (
echo Failed to download installer
exit /b 1
) else (
goto checkpy
)
)
REM It should exist at this point - let's run it to install silently
echo Installing...
pushd "%TEMP%"
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!"
)
popd
echo Installer finished with %ERRORLEVEL% status.
REM Now we should be able to delete the installer and check for py again
del "%TEMP%\pyinstall.!pytype!"
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
if /i "!just_installing!" == "TRUE" (
echo.
echo Done.
) else (
goto checkpy
)
exit /b
:runscript
REM Python found
cls
set "args=%*"
set "args=!args:"=!"
if "!args!"=="" (
"!pypath!" "!thisDir!!script_name!"
) else (
"!pypath!" "!thisDir!!script_name!" %*
)
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
)
)
goto :EOF
:undouble <string_name> <string_value> <character>
REM Helper function to strip doubles of a single character out of a string recursively
set "string_value=%~2"
:undouble_continue
set "check=!string_value:%~3%~3=%~3!"
if not "!check!" == "!string_value!" (
set "string_value=!check!"
goto :undouble_continue
)
set "%~1=!check!"
goto :EOF
:updatepath
set "spath="
set "upath="
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" )
if not "%spath%" == "" (
REM We got something in the system path
set "PATH=%spath%"
if not "%upath%" == "" (
REM We also have something in the user path
set "PATH=%PATH%;%upath%"
)
) else if not "%upath%" == "" (
set "PATH=%upath%"
)
REM Remove double semicolons from the adjusted PATH
call :undouble "PATH" "%PATH%" ";"
goto :EOF
:getsyspath <variable_name>
REM Helper method to return a valid path to cmd.exe, reg.exe, and where.exe by
REM walking the ComSpec var - will also repair it in memory if need be
REM Strip double semi-colons
call :undouble "temppath" "%ComSpec%" ";"
REM Dirty hack to leverage the "line feed" approach - there are some odd side
REM effects with this. Do not use this variable name in comments near this
REM line - as it seems to behave erradically.
(set LF=^
%=this line is empty=%
)
REM Replace instances of semi-colons with a line feed and wrap
REM in parenthesis to work around some strange batch behavior
set "testpath=%temppath:;=!LF!%"
REM Let's walk each path and test if cmd.exe, reg.exe, and where.exe exist there
set /a found=0
for /f "tokens=* delims=" %%i in ("!testpath!") do (
REM Only continue if we haven't found it yet
if not "%%i" == "" (
if !found! lss 1 (
set "checkpath=%%i"
REM Remove "cmd.exe" from the end if it exists
if /i "!checkpath:~-7!" == "cmd.exe" (
set "checkpath=!checkpath:~0,-7!"
)
REM Pad the end with a backslash if needed
if not "!checkpath:~-1!" == "\" (
set "checkpath=!checkpath!\"
)
REM Let's see if cmd, reg, and where exist there - and set it if so
if EXIST "!checkpath!cmd.exe" (
if EXIST "!checkpath!reg.exe" (
if EXIST "!checkpath!where.exe" (
set /a found=1
set "ComSpec=!checkpath!cmd.exe"
set "%~1=!checkpath!"
)
)
)
)
)
)
goto :EOF

View File

@ -3,7 +3,7 @@
# Get the curent directory, the script name
# and the script name with "py" substituted for the extension.
args=( "$@" )
dir="${0%/*}"
dir="$(cd -- "$(dirname "$0")" >/dev/null 2>&1; pwd -P)"
script="${0##*/}"
target="${script%.*}.py"