Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 74 additions & 121 deletions GenSMBIOS.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,13 @@ set "thisDir=%~dp0"

setlocal enableDelayedExpansion
REM Setup initial vars
set "script_name="
set "script_name=%~n0.py"
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
Expand Down Expand Up @@ -66,19 +54,16 @@ if "%~1" == "--install-python" (
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"
)
)
REM Check for our script
if not exist "!thisDir!\!script_name!" (
echo Could not find !looking_for!.
cls
echo ### ###
echo # Script Not Found #
echo ### ###
echo.
echo Could not find !script_name!.
echo Please make sure to run this script from the same directory
echo as !looking_for!.
echo as !script_name!.
echo.
echo Press [enter] to quit.
pause > nul
Expand All @@ -88,79 +73,49 @@ 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" (
for /f "USEBACKQ tokens=*" %%x in (`!syspath!where.exe python3 2^> nul`) do ( call :checkpyversion "%%x" "py3v" "py3path" )
if not "!py3path!" == "" (
set "pypath=!py3path!"
if "!pypath!" == "" set "pypath=!py2path!"
)
if not "!pypath!" == "" (
goto runscript
goto setupvenv
)
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 ### ###
echo # Python Not Found #
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 Python 3 is not installed or not found in your PATH.
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 "Add Python 3.X to PATH"
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>
:checkpyversion <path> <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
if "!version:~0,1!" == "3" (
REM Python 3
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

Expand All @@ -169,7 +124,7 @@ 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>
:comparepyversion <version1> <version2>
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
Expand Down Expand Up @@ -201,23 +156,18 @@ echo ### ###
echo # Python Not Found #
echo ### ###
echo.
echo Python !targetpy! was not found on the system or in the PATH var.
echo Python 3 was not found on the system or in the PATH.
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 ### ###
Expand All @@ -226,8 +176,6 @@ 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
Expand All @@ -238,8 +186,7 @@ if not exist "%TEMP%\pyurl.txt" (
)
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" )
for /f "tokens=9 delims=< " %%x in ('findstr /i /c:"Latest Python 3 Release" pyurl.txt') do ( set "release=%%x" )
popd
if "!release!" == "" (
if /i "!just_installing!" == "TRUE" (
Expand All @@ -250,19 +197,10 @@ if "!release!" == "" (
)
)
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
Expand All @@ -271,42 +209,74 @@ if not exist "%TEMP%\pyinstall.!pytype!" (
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!"
)
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
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.
pause > nul
exit /b 0
) else (
goto checkpy
)
exit /b

:setupvenv
REM Create virtual environment if it doesn't exist
set "venv_dir=!thisDir!.venv"
if not exist "!venv_dir!\Scripts\python.exe" (
echo Creating virtual environment...
"!pypath!" -m venv "!venv_dir!"
if not !ERRORLEVEL! == 0 (
echo Failed to create virtual environment. Falling back to base Python.
set "venv_python=!pypath!"
) else (
set "venv_python=!venv_dir!\Scripts\python.exe"
)
) else (
set "venv_python=!venv_dir!\Scripts\python.exe"
)
REM Upgrade pip in venv
"!venv_python!" -m pip install --upgrade pip >nul 2>&1
REM Check and install required modules in venv
echo Checking Python modules...
"!venv_python!" -c "import tqdm" >nul 2>&1
if not !ERRORLEVEL! == 0 (
echo tqdm not found. Attempting to install in venv...
"!venv_python!" -m pip install tqdm >nul 2>&1
if not !ERRORLEVEL! == 0 (
echo Failed to install tqdm. Continuing without it...
)
)
"!venv_python!" -c "import requests" >nul 2>&1
if not !ERRORLEVEL! == 0 (
echo requests not found. Attempting to install in venv...
"!venv_python!" -m pip install requests >nul 2>&1
if not !ERRORLEVEL! == 0 (
echo Failed to install requests. The script may not run without it...
)
)
"!venv_python!" -c "import tkinter" >nul 2>&1
if not !ERRORLEVEL! == 0 (
echo tkinter module not found.
echo Python on Windows typically includes tkinter. Continuing without it...
)
goto runscript

:runscript
REM Python found
REM Run the Python script
cls
set "args=%*"
set "args=!args:"=!"
if "!args!"=="" (
"!pypath!" "!thisDir!!script_name!"
"!venv_python!" "!thisDir!!script_name!"
) else (
"!pypath!" "!thisDir!!script_name!" %*
"!venv_python!" "!thisDir!!script_name!" %*
)
if /i "!pause_on_error!" == "yes" (
if not "%ERRORLEVEL%" == "0" (
Expand Down Expand Up @@ -337,51 +307,34 @@ 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
REM Helper method to return a valid path to cmd.exe, reg.exe, and where.exe
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" (
Expand All @@ -394,4 +347,4 @@ for /f "tokens=* delims=" %%i in ("!testpath!") do (
)
)
)
goto :EOF
goto :EOF
Loading