Files
my-botty/install.bat
alexpolo1 3d12a75b72 feat(install): actionable error messages instead of dead ends
Every fatal message told the user THAT something failed but not what to do
about it. The worst was "conda env create failed. See output above." --
useless when run_install_capture.bat redirects that output to a 56 KB log.

Each error now names the likely cause and the concrete next step:
  - download failed      -> the URL tried, firewall/proxy hint, manual-install
                            fallback that install.bat will detect on re-run
  - truncated download   -> got N bytes vs expected ~78 MB, bad file deleted
  - installer failed     -> antivirus/UAC hint, how to run it by hand
  - conda found but dead -> the exact command to reproduce the real error
  - env create failed    -> disk/network/antivirus causes, plus the
                            "env remove -n botty -y" recovery for a half
                            finished install
  - pip install failed   -> notes the env itself is fine and a re-run resumes
  - python.exe missing   -> explains partial env, gives the recovery commands
  - find_python.bat      -> distinguishes "never installed" from "install.bat
                            did not finish", pointing at the capture log

Added a shared ":fail" exit so every fatal path ends with how to produce a
full log for a bug report, and states that nothing else was changed.

Also added a disk-space pre-flight before env creation: under 3 GB now
fails immediately with a clear message instead of letting conda die halfway
through with an opaque error; 3-6 GB warns. The environment needs ~4 GB
plus ~1 GB of downloads.

Verified: install.bat still completes with exit 0; the pre-flight was
exercised at real, simulated-2 GB and simulated-5 GB levels and all three
branches render and exit correctly; find_python.bat still resolves; 140
tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 22:29:23 +02:00

625 lines
25 KiB
Batchfile

@echo off
setlocal enabledelayedexpansion
:: Always run from the folder this script lives in
cd /d "%~dp0"
echo ============================================
echo Botty - Dependency Installer
echo ============================================
echo.
:: --- Detect Windows version ---
for /f "tokens=3" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuild 2^>nul') do set "WIN_BUILD=%%A"
if not defined WIN_BUILD (
echo WARNING: Could not detect Windows build number.
set "WIN_BUILD=0"
)
echo Detected Windows build: %WIN_BUILD%
set /a "WIN_BUILD_NUM=%WIN_BUILD%" 2>nul || set "WIN_BUILD_NUM=0"
if %WIN_BUILD_NUM% GEQ 22000 (
echo Detected Windows 11 -- using relative mouse mode ^(no ABSOLUTE flag^)
set "WIN11=1"
set "REQ_FILE=requirements-win11.txt"
set "ENV_FILE=environment-win11.yml"
) else (
echo Detected Windows 10 or earlier — using absolute mouse mode
set "WIN11=0"
set "REQ_FILE=requirements-win10.txt"
set "ENV_FILE=environment-win10.yml"
)
if not exist "%REQ_FILE%" set "REQ_FILE=requirements.txt"
if not exist "%ENV_FILE%" set "ENV_FILE=environment.yml"
echo Requirements profile: %REQ_FILE%
echo Environment profile: %ENV_FILE%
echo.
:: --- Find conda ---
:: Miniforge3 JustMe default: %LOCALAPPDATA%\miniforge3 (newer) or
:: %USERPROFILE%\miniforge3 (older)
set "CONDA_EXE="
for %%C in (
"%LOCALAPPDATA%\miniforge3\Scripts\conda.exe"
"%USERPROFILE%\miniforge3\Scripts\conda.exe"
"%LOCALAPPDATA%\miniconda3\Scripts\conda.exe"
"%USERPROFILE%\miniconda3\Scripts\conda.exe"
"%USERPROFILE%\anaconda3\Scripts\conda.exe"
"%ProgramData%\miniforge3\Scripts\conda.exe"
"%ProgramData%\miniconda3\Scripts\conda.exe"
"%ProgramData%\anaconda3\Scripts\conda.exe"
) do (
if exist %%C (
set "CONDA_EXE=%%~C"
goto :found_conda
)
)
echo conda not found — installing Miniforge3 automatically...
echo This is a one-time setup (~100 MB). Please wait.
echo.
:: --- Method 1: winget (cleanest; available on Win10 1709+ and all Win11) ---
:: --scope user is critical: without it winget defaults to a machine-wide
:: install (lands in %ProgramData%) which REQUIRES admin. A normal double-click
:: (no elevation) then fails silently and conda never installs. --scope user
:: installs to %USERPROFILE%\miniforge3 with no admin needed — which is also one
:: of the locations :rescan_conda searches.
:: winget returns non-zero when the package is already installed, so don't
:: trust the exit code -- rescan for conda and only fall through to the direct
:: download if it's genuinely still missing. Keep this comment outside the block:
:: a "::" line inside a ( ) block is a parse error.
winget --version >nul 2>&1
if %errorlevel% equ 0 (
echo Installing via winget...
winget install --id CondaForge.Miniforge3 --exact --silent --scope user ^
--accept-package-agreements --accept-source-agreements
for %%C in (
"%LOCALAPPDATA%\miniforge3\Scripts\conda.exe"
"%USERPROFILE%\miniforge3\Scripts\conda.exe"
"%ProgramData%\miniforge3\Scripts\conda.exe"
) do if exist %%C goto :rescan_conda
echo winget did not produce a usable conda — falling back to direct download.
echo.
)
:: --- Method 2: direct download + silent NSIS install ---
:: Uses curl (built into Win10/11) with PowerShell as fallback.
:: $ProgressPreference=SilentlyContinue is critical — without it PowerShell's
:: progress bar drops download speed from ~50 MB/s to ~1 MB/s.
:: start /wait "" is required: plain "installer /S" can return before install
:: finishes. /D= intentionally omitted — NSIS /D= breaks on paths with spaces.
set "MF_INSTALLER=%TEMP%\Miniforge3-installer.exe"
set "MF_URL=https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Windows-x86_64.exe"
del /q "%MF_INSTALLER%" >nul 2>&1
echo Downloading Miniforge3...
curl -Lk --progress-bar "%MF_URL%" -o "%MF_INSTALLER%" 2>&1
if %errorlevel% neq 0 (
echo curl failed, trying PowerShell...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"$ProgressPreference='SilentlyContinue'; try { Invoke-WebRequest -Uri '%MF_URL%' -OutFile '%MF_INSTALLER%' -UseBasicParsing; exit 0 } catch { Write-Host $_.Exception.Message; exit 1 }"
)
if not exist "%MF_INSTALLER%" (
echo.
echo ERROR: Could not download Miniforge3 ^(the Python/conda runtime^).
echo.
echo Nothing was downloaded from:
echo %MF_URL%
echo Usual causes: no internet, or a firewall/proxy blocking github.com.
echo.
echo Workaround: install Miniforge yourself, then run install.bat again.
echo It will detect it and carry on:
echo https://github.com/conda-forge/miniforge/releases/latest
echo ^(pick Miniforge3-Windows-x86_64.exe and keep the default location^)
goto :fail
)
:: Verify the download is a real installer, not a truncated file or an HTML
:: error page served with a 200. The Miniforge installer is ~78 MB; anything
:: under 40 MB means the download failed even though a file exists.
for %%A in ("%MF_INSTALLER%") do set "MF_SIZE=%%~zA"
if not defined MF_SIZE set "MF_SIZE=0"
if %MF_SIZE% LSS 41943040 (
echo.
echo ERROR: The Miniforge3 download is incomplete and was not run.
echo Got: %MF_SIZE% bytes
echo Expected: about 78 MB
echo.
echo The connection dropped, or a proxy/filter returned an error page
echo instead of the file. The bad file has been deleted.
echo.
echo Try again on a different network, or install Miniforge yourself and
echo re-run install.bat:
echo https://github.com/conda-forge/miniforge/releases/latest
del /q "%MF_INSTALLER%" >nul 2>&1
goto :fail
)
echo Installing Miniforge3 (this takes ~1 minute)...
start /wait "" "%MF_INSTALLER%" /S /InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /NoShortcuts=1 /NoRegistry=1
if %errorlevel% neq 0 (
echo.
echo ERROR: The Miniforge3 installer did not complete ^(exit code %errorlevel%^).
echo.
echo Usual causes: antivirus blocked it, or a UAC prompt was declined.
echo.
echo Run it by hand to see the real error, accepting any prompts:
echo %MF_INSTALLER%
echo then run install.bat again.
goto :fail
)
del /q "%MF_INSTALLER%" >nul 2>&1
echo Miniforge3 installed.
:rescan_conda
echo.
:: Re-scan for conda now that Miniforge is installed
for %%C in (
"%LOCALAPPDATA%\miniforge3\Scripts\conda.exe"
"%USERPROFILE%\miniforge3\Scripts\conda.exe"
"%LOCALAPPDATA%\miniconda3\Scripts\conda.exe"
"%USERPROFILE%\miniconda3\Scripts\conda.exe"
"%USERPROFILE%\anaconda3\Scripts\conda.exe"
"%ProgramData%\miniforge3\Scripts\conda.exe"
"%ProgramData%\miniconda3\Scripts\conda.exe"
"%ProgramData%\anaconda3\Scripts\conda.exe"
) do (
if exist %%C (
set "CONDA_EXE=%%~C"
goto :found_conda
)
)
echo ERROR: Miniforge3 reported success but conda.exe cannot be found.
echo.
echo install.bat looked in every standard location, including:
echo %%LOCALAPPDATA%%\miniforge3\Scripts\conda.exe
echo %%USERPROFILE%%\miniforge3\Scripts\conda.exe
echo %%ProgramData%%\miniforge3\Scripts\conda.exe
echo.
echo If you installed conda somewhere custom, the simplest fix is to
echo install Miniforge to its default location:
echo https://github.com/conda-forge/miniforge/releases/latest
echo then run install.bat again.
goto :fail
:found_conda
echo Found conda: %CONDA_EXE%
echo.
:: --- Test conda works ---
echo Testing conda...
"%CONDA_EXE%" --version >nul 2>&1
if %errorlevel% neq 0 (
echo.
echo ERROR: conda was found but will not run.
echo Location: %CONDA_EXE%
echo.
echo The install is damaged or blocked. Try, in order:
echo 1. Run this by hand to see the real error:
echo "%CONDA_EXE%" --version
echo 2. Check antivirus is not quarantining conda
echo 3. Reinstall Miniforge, then run install.bat again:
echo https://github.com/conda-forge/miniforge/releases/latest
goto :fail
)
echo conda is working.
echo.
:: --- Find botty Python ---
set "PYTHON="
for %%C in (
"%LOCALAPPDATA%\miniforge3\envs\botty\python.exe"
"%LOCALAPPDATA%\miniconda3\envs\botty\python.exe"
"%USERPROFILE%\miniforge3\envs\botty\python.exe"
"%USERPROFILE%\miniconda3\envs\botty\python.exe"
"%USERPROFILE%\anaconda3\envs\botty\python.exe"
"%ProgramData%\miniforge3\envs\botty\python.exe"
"%ProgramData%\miniconda3\envs\botty\python.exe"
"%ProgramData%\anaconda3\envs\botty\python.exe"
) do (
if exist %%C (
set "PYTHON=%%~C"
goto :check_env
)
)
:: --- Pre-flight: free disk space ---
:: The botty env is ~4 GB once conda unpacks it, plus ~1 GB of downloaded
:: package archives. Running out midway makes conda fail with a long, opaque
:: error, so check up front and say so plainly instead.
set "FREE_GB="
for /f "delims=" %%A in ('powershell -NoProfile -Command "[int]((Get-PSDrive %SystemDrive:~0,1%).Free/1GB)" 2^>nul') do set "FREE_GB=%%A"
if defined FREE_GB (
echo Free disk space: %FREE_GB% GB
if %FREE_GB% LSS 3 (
echo.
echo ERROR: Not enough free disk space on %SystemDrive%
echo Free now: %FREE_GB% GB
echo Needed: about 6 GB ^(the botty environment is ~4 GB, plus
echo ~1 GB of package downloads^)
echo.
echo Free up space and run install.bat again. Quick wins:
echo - Empty the Recycle Bin
echo - Windows Settings ^> System ^> Storage ^> Temporary files
echo - Uninstall apps you no longer use
goto :fail
)
if %FREE_GB% LSS 6 (
echo WARNING: Only %FREE_GB% GB free. The install needs about 6 GB and
echo may fail partway. Free up space if it does.
)
)
:: --- Create botty env ---
echo Creating 'botty' conda environment...
"%CONDA_EXE%" env create -f "%ENV_FILE%"
if %errorlevel% neq 0 (
echo.
echo ERROR: Could not create the 'botty' conda environment.
echo.
echo The detailed reason is in the conda output above this message.
echo Most common causes:
echo - Out of disk space ^(needs about 6 GB free^)
echo - No internet, or a company/school network blocking conda-forge
echo - Antivirus blocking conda while it unpacks files
echo - A previous half-finished install: run this to clear it, then retry
echo "%CONDA_EXE%" env remove -n botty -y
goto :fail
)
:check_env
:: Re-scan for Python after env creation
set "PYTHON="
for %%C in (
"%LOCALAPPDATA%\miniforge3\envs\botty\python.exe"
"%LOCALAPPDATA%\miniconda3\envs\botty\python.exe"
"%USERPROFILE%\miniforge3\envs\botty\python.exe"
"%USERPROFILE%\miniconda3\envs\botty\python.exe"
"%USERPROFILE%\anaconda3\envs\botty\python.exe"
"%ProgramData%\miniforge3\envs\botty\python.exe"
"%ProgramData%\miniconda3\envs\botty\python.exe"
"%ProgramData%\anaconda3\envs\botty\python.exe"
) do (
if exist %%C (
set "PYTHON=%%~C"
goto :env_ready
)
)
echo.
echo ERROR: The 'botty' environment exists but its python.exe is missing.
echo.
echo This usually means the environment was only partly created -- often
echo because the install ran out of disk space, or antivirus removed files
echo while conda was unpacking them.
echo.
echo Fix: delete the environment and install again:
echo "%CONDA_EXE%" env remove -n botty -y
echo install.bat
goto :fail
:env_ready
echo Botty Python: %PYTHON%
:: --- Install pip requirements ---
:: --progress-bar off: pip's progress bar uses \r to redraw in place; when this
:: script's output is redirected to a file (e.g. run_install_capture.bat) those
:: redraws become millions of lines and the log balloons to many GB. Turning the
:: bar off keeps the install log small without hiding warnings/errors.
echo.
echo Installing Botty requirements from %REQ_FILE%...
"%CONDA_EXE%" run -n botty python -m pip install --progress-bar off -r "%REQ_FILE%"
if %errorlevel% neq 0 (
echo.
echo ERROR: Could not install the Python packages from %REQ_FILE%.
echo.
echo The failing package and reason are in the pip output above.
echo Most common causes:
echo - No internet, or a proxy/firewall blocking pypi.org
echo - Out of disk space
echo - Antivirus blocking pip while it writes files
echo.
echo The conda environment itself is fine -- you can just run
echo install.bat again; it will skip straight to this step.
goto :fail
)
echo.
echo Botty osdetect:
"%CONDA_EXE%" run -n botty python -c "import sys; sys.path.insert(0, 'src'); from utils.os_detect import describe_current_os; print(describe_current_os())"
:: --- OCR setup ---
:: Two OCR backends, tried in order at runtime:
:: 1. tesserocr — C extension calling tesseract DLLs directly (fast)
:: 2. pytesseract — subprocess calling tesseract.exe (always works if exe exists)
:: At least one must work. Install.bat sets up both and reports which is ready.
echo.
echo Setting up OCR...
:: Find the botty env directory
set "BOTTY_ENV_DIR="
for %%C in (
"%LOCALAPPDATA%\miniforge3\envs\botty"
"%LOCALAPPDATA%\miniconda3\envs\botty"
"%USERPROFILE%\miniforge3\envs\botty"
"%USERPROFILE%\miniconda3\envs\botty"
"%USERPROFILE%\anaconda3\envs\botty"
"%ProgramData%\miniforge3\envs\botty"
"%ProgramData%\miniconda3\envs\botty"
"%ProgramData%\anaconda3\envs\botty"
) do (
if exist %%C (
set "BOTTY_ENV_DIR=%%~C"
goto :env_found
)
)
echo ERROR: Could not locate the 'botty' environment folder.
echo.
echo Python was found but the environment directory around it was not,
echo which means the conda install is in an unexpected layout.
echo Fix: remove and recreate the environment:
echo "%CONDA_EXE%" env remove -n botty -y
echo install.bat
goto :fail
:env_found
set "TESS_PATH=%BOTTY_ENV_DIR%\Library\bin;%BOTTY_ENV_DIR%\Library\lib;%BOTTY_ENV_DIR%\DLLs;%BOTTY_ENV_DIR%\Scripts"
:: --- Backend 1: tesserocr (fast path, best-effort) ---
:: tesserocr uses the C++ API of tesseract and needs an MSVC-compiled tesseract DLL.
:: The bundled dependencies folder provides:
:: tesseract52.dll — MSVC tesseract 5.2.0 (conda-forge, compiled vs2019)
:: tesserocr.cp310-...pyd — MSVC tesserocr 2.5.2 linked against tesseract52.dll
:: (both require leptonica-1.78.0.dll from the conda tesseract=4.x install below)
:: If any step fails the bot still works via pytesseract below.
:: Remove any existing pip/wheel tesserocr
"%PYTHON%" -m pip uninstall tesserocr -y >nul 2>&1
:: conda tesseract 4.x provides leptonica-1.78.0.dll (MSVC) which tesseract52.dll needs.
:: libdeflate is required explicitly: the libtiff that ships with tesseract 4.x
:: imports libdeflate, and without it the whole chain below fails to load.
"%CONDA_EXE%" install -n botty "tesseract=4.*" libdeflate -c conda-forge -y >nul 2>&1
:: libdeflate.dll compatibility alias.
:: THIS IS WHAT MAKES tesserocr WORK. The DLL chain is:
:: tesserocr.pyd -> tesseract52.dll -> leptonica-1.78.0.dll -> tiff.dll -> libdeflate.dll
:: Current conda-forge libdeflate (>=1.20) installs the library as "deflate.dll",
:: but the older tiff.dll from the tesseract=4.x stack still imports the previous
:: name "libdeflate.dll". Nothing provides that name, so tiff.dll fails to load,
:: and every DLL above it in the chain fails with WinError 126 ("The specified
:: module could not be found") -- which surfaced as tesserocr being permanently
:: unavailable and the bot silently falling back to the slower pytesseract.
:: Copying deflate.dll to the old name satisfies the import; the exported symbols
:: are the same library, verified by tesserocr initialising and running real OCR.
if not exist "%BOTTY_ENV_DIR%\Library\bin\libdeflate.dll" (
if exist "%BOTTY_ENV_DIR%\Library\bin\deflate.dll" (
copy /y "%BOTTY_ENV_DIR%\Library\bin\deflate.dll" "%BOTTY_ENV_DIR%\Library\bin\libdeflate.dll" >nul
)
)
:: conda tesseract.exe crashes on Win10 and Win11 — disable it, keep the DLLs
if exist "%BOTTY_ENV_DIR%\Library\bin\tesseract.exe" (
rename "%BOTTY_ENV_DIR%\Library\bin\tesseract.exe" "tesseract_disabled.exe" >nul 2>&1
)
:: Deploy the MSVC tesseract52.dll (tesserocr.pyd imports exactly this name)
if exist "dependencies\tesseract52.dll" (
copy /y "dependencies\tesseract52.dll" "%BOTTY_ENV_DIR%\Library\bin\tesseract52.dll" >nul
)
:: Deploy the conda-forge tesserocr .pyd (compiled against tesseract52.dll)
if exist "dependencies\tesserocr.cp310-win_amd64.pyd" (
copy /y "dependencies\tesserocr.cp310-win_amd64.pyd" "%BOTTY_ENV_DIR%\lib\site-packages\tesserocr.cp310-win_amd64.pyd" >nul
) else if exist "dependencies\tesserocr-2.5.2-cp310-cp310-win_amd64.whl" (
"%CONDA_EXE%" run -n botty python -m pip install --quiet --force-reinstall --no-deps "dependencies\tesserocr-2.5.2-cp310-cp310-win_amd64.whl" >nul 2>&1
)
:: --- Backend 2: pytesseract (reliable fallback) ---
:: This is the backend that actually carries OCR on most machines (tesserocr's
:: MSVC DLL chain frequently fails), so it must install without admin rights and
:: without winget -- neither is guaranteed on a clean Win10 box.
"%CONDA_EXE%" run -n botty python -m pip install --progress-bar off pytesseract >nul 2>&1
if %errorlevel% neq 0 (
echo WARNING: Could not install pytesseract Python wrapper.
)
:: Try winget machine scope, then user scope -- the latter needs no admin.
:: winget's exit code is unreliable, being non-zero when the package is already
:: installed, so after each attempt we re-resolve tesseract.exe instead of
:: trusting errorlevel.
:: NOTE: comments must stay OUTSIDE the parenthesised blocks below. A "::" line
:: inside a ( ) block is a parse error, and any parenthesis in the comment text
:: closes the block early.
call :find_tesseract
if not defined TESS_EXE (
echo Installing Tesseract OCR...
winget --version >nul 2>&1
if !errorlevel! equ 0 (
winget install --id tesseract-ocr.tesseract --exact --silent ^
--accept-package-agreements --accept-source-agreements >nul 2>&1
call :find_tesseract
if not defined TESS_EXE (
winget install --id tesseract-ocr.tesseract --exact --silent --scope user ^
--accept-package-agreements --accept-source-agreements >nul 2>&1
call :find_tesseract
)
)
)
:: Last resort: direct download of the official NSIS installer. Covers clean
:: Win10 machines where winget is missing or fails.
:: The size check guards against a truncated download or an HTML error page;
:: the installer is ~50 MB.
:: NOTE on /D=: measured behaviour is that the official Tesseract installer
:: self-elevates (it requests admin) and the elevated relaunch DISCARDS /D=, so
:: it always lands machine-wide in "C:\Program Files\Tesseract-OCR" regardless
:: of TS_DEST. /D= is kept as best-effort only. The practical consequence is
:: that Tesseract needs admin/UAC -- there is no per-user install path with the
:: official installer. Either outcome is fine at runtime because find_tesseract
:: and src\d2r_image\ocr.py both search the machine-wide and per-user paths.
:: /D= must still come last and unquoted, and breaks on paths with spaces, so
:: it is only passed when the target path has none.
if not defined TESS_EXE (
echo winget unavailable or failed -- downloading Tesseract directly...
set "TS_INSTALLER=%TEMP%\tesseract-setup.exe"
set "TS_URL=https://github.com/tesseract-ocr/tesseract/releases/download/5.5.0/tesseract-ocr-w64-setup-5.5.0.20241111.exe"
set "TS_DEST=%LOCALAPPDATA%\Programs\Tesseract-OCR"
del /q "!TS_INSTALLER!" >nul 2>&1
curl -Lk --progress-bar "!TS_URL!" -o "!TS_INSTALLER!" 2>&1
if not exist "!TS_INSTALLER!" (
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"$ProgressPreference='SilentlyContinue'; try { Invoke-WebRequest -Uri '!TS_URL!' -OutFile '!TS_INSTALLER!' -UseBasicParsing; exit 0 } catch { exit 1 }"
)
set "TS_SIZE=0"
if exist "!TS_INSTALLER!" for %%A in ("!TS_INSTALLER!") do set "TS_SIZE=%%~zA"
if !TS_SIZE! GEQ 20971520 (
echo !TS_DEST! | find " " >nul
if !errorlevel! equ 0 (
start /wait "" "!TS_INSTALLER!" /S
) else (
start /wait "" "!TS_INSTALLER!" /S /D=!TS_DEST!
)
del /q "!TS_INSTALLER!" >nul 2>&1
call :find_tesseract
)
)
if defined TESS_EXE (
echo Tesseract: !TESS_EXE!
) else (
echo WARNING: Tesseract could not be installed automatically. Install manually:
echo https://github.com/tesseract-ocr/tesseract/releases
echo Download the win64 installer, run it, then re-run install.bat.
)
:: --- Verify OCR: at least one backend must work ---
echo.
echo Checking OCR backends...
set "PATH=%TESS_PATH%;%PATH%"
set "OCR_READY=0"
"%CONDA_EXE%" run -n botty python -c "import os; os.add_dll_directory(r'%BOTTY_ENV_DIR%\Library\bin'); from tesserocr import PyTessBaseAPI, OEM; PyTessBaseAPI(psm=7,oem=OEM.LSTM_ONLY,path='assets/tessdata',lang='hover-eng_inconsolata_inv_th_fast').End()" >nul 2>&1
if %errorlevel% == 0 (
echo tesserocr: OK ^(fast path^)
set "OCR_READY=1"
) else (
echo tesserocr: not available ^(DLL issue -- bot will use pytesseract instead^)
)
if defined TESS_EXE (
"%CONDA_EXE%" run -n botty python -c "import pytesseract; pytesseract.pytesseract.tesseract_cmd=r'!TESS_EXE!'; pytesseract.get_tesseract_version()" >nul 2>&1
if !errorlevel! == 0 (
echo pytesseract: OK ^(reliable fallback^)
set "OCR_READY=1"
) else (
echo pytesseract: tesseract.exe found but call failed
)
) else (
echo pytesseract: tesseract.exe not found -- install from link above if needed
)
if "%OCR_READY%"=="0" (
echo.
echo WARNING: No OCR backend is working. Item hover text will not be read.
echo Install Tesseract OCR: https://github.com/tesseract-ocr/tesseract/releases
echo Then re-run install.bat.
)
:: --- Verify all dependencies ---
echo.
echo Verifying all dependencies...
set "ALL_OK=1"
for %%M in (cv2 mss numpy transitions rapidfuzz pydantic pytesseract yaml) do (
set "PATH=%TESS_PATH%;%PATH%"
"%CONDA_EXE%" run -n botty python -c "import %%M" >nul 2>&1
if !errorlevel! neq 0 (
echo FAILED: %%M
set "ALL_OK=0"
) else (
echo %%M: OK
)
)
:: discord.py imports aiohttp which calls ssl.create_default_context() at import
:: time. A malformed cert in the Windows store triggers ASN1 NOT_ENOUGH_DATA.
:: The bot patches this at runtime via _patch_ssl(); check import with the patch.
set "PATH=%TESS_PATH%;%PATH%"
"%CONDA_EXE%" run -n botty python -c "import ssl; ssl.SSLContext.load_default_certs = lambda *a, **kw: None; import discord" >nul 2>&1
if !errorlevel! neq 0 (
echo FAILED: discord
set "ALL_OK=0"
) else (
echo discord: OK
)
if "%OCR_READY%"=="0" set "ALL_OK=0"
if "%ALL_OK%"=="1" (
echo.
echo All dependencies verified.
) else (
echo.
echo WARNING: Some dependencies failed above.
echo This is often a PATH issue. Try running from a fresh CMD/PowerShell:
echo conda activate botty
echo python -c "import cv2"
echo.
)
:install_done
echo.
echo ============================================
echo Installation complete!
echo Run botty with: run_botty.bat
echo ============================================
echo.
:: Hold the window open. Every failure path already pauses, but the success
:: path did not -- so a user double-clicking install.bat from Explorer saw the
:: console vanish the instant it finished and never got to read the result or
:: the dependency/OCR verification above. Redirected runs are unaffected:
:: run_install_capture.bat feeds stdin from the log redirect, and any
:: non-interactive run should invoke this script with "< nul".
pause
goto :eof
:: --- Shared failure exit ---
:: Every fatal path jumps here with "goto :fail" after printing what went wrong
:: and how to fix it. This adds the one instruction that makes a bug report
:: actionable: how to produce a full log.
:fail
echo.
echo ------------------------------------------------------------
echo INSTALL FAILED - nothing else was changed on your PC.
echo.
echo Still stuck? Produce a full log and include it when asking
echo for help:
echo 1. Double-click run_install_capture.bat
echo 2. Attach the install_log.txt it creates
echo ------------------------------------------------------------
echo.
pause
exit /b 1
:: --- Resolve tesseract.exe into TESS_EXE ---
:: Checks machine-wide (winget default / manual install) and per-user (winget
:: --scope user / our direct NSIS fallback) locations, plus PATH. Sets TESS_EXE
:: to the first hit, or clears it if none found.
:find_tesseract
set "TESS_EXE="
for %%T in (
"C:\Program Files\Tesseract-OCR\tesseract.exe"
"C:\Program Files (x86)\Tesseract-OCR\tesseract.exe"
"%LOCALAPPDATA%\Programs\Tesseract-OCR\tesseract.exe"
"%ProgramData%\Tesseract-OCR\tesseract.exe"
) do (
if exist %%T (
set "TESS_EXE=%%~T"
goto :eof
)
)
for /f "delims=" %%T in ('where tesseract 2^>nul') do (
set "TESS_EXE=%%T"
goto :eof
)
goto :eof