fix: use conda run instead of direct python for DLL loading
Every approach to manually replicating conda's DLL environment from Python code or batch PATH manipulation has failed. conda run activates the environment exactly like "conda activate botty" — setting PATH, running activate.d scripts, and properly resolving all transitive DLL dependencies for tesseract51.dll. run_botty.bat now derives conda.exe from the botty python.exe path (two levels up: envs/botty -> envs -> miniforge3 -> Scripts/conda.exe) and uses "conda run -n botty --no-capture-output python src/main.py". install.bat smoke test now uses "%CONDA_EXE% run -n botty python -c ..." which already has CONDA_EXE set from the install step. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
bdd6247342
commit
e1c18faf26
+4
-10
@@ -91,27 +91,21 @@ exit /b 1
|
||||
:env_created
|
||||
echo Botty Python: %PYTHON%
|
||||
|
||||
:: Prepend conda DLL dirs to PATH at the process level so the Windows DLL
|
||||
:: loader finds tesseract51.dll's transitive deps (leptonica, zlib, etc.)
|
||||
:: when ctypes loads it. os.environ['PATH'] set from inside Python is too late.
|
||||
for %%F in ("%PYTHON%") do set "_CONDA_ENV=%%~dpF"
|
||||
set "_CONDA_ENV=%_CONDA_ENV:~0,-1%"
|
||||
set "PATH=%_CONDA_ENV%\Library\bin;%_CONDA_ENV%\Library\mingw-w64\bin;%_CONDA_ENV%\Library\usr\bin;%PATH%"
|
||||
|
||||
:: --- Force-reinstall the tesserocr wheel so the correct binary is always used ---
|
||||
echo.
|
||||
echo Installing tesserocr wheel...
|
||||
"%PYTHON%" -m pip install --force-reinstall "%~dp0dependencies\tesserocr-2.5.2-cp310-cp310-win_amd64.whl" >nul 2>&1
|
||||
|
||||
:: --- Smoke test: import key dependencies ---
|
||||
:: --- Smoke test via conda run (activates the full env like "conda activate botty") ---
|
||||
:: This is the only reliable way to ensure all DLL transitive deps are resolved.
|
||||
echo.
|
||||
echo Verifying dependencies...
|
||||
"%PYTHON%" -c "import os,sys,ctypes;d=[x for x in [os.path.join(sys.prefix,'Library',s) for s in ['bin','mingw-w64\\bin','usr\\bin']] if os.path.isdir(x)];[os.add_dll_directory(x) for x in d];f=ctypes.windll.kernel32.LoadLibraryExW;f.restype=ctypes.c_void_p;f.argtypes=[ctypes.c_wchar_p,ctypes.c_void_p,ctypes.c_ulong];[f(os.path.join(x,'tesseract51.dll'),None,0x1000) for x in d if os.path.isfile(os.path.join(x,'tesseract51.dll'))];import cv2,mss,numpy,tesserocr,discord,transitions,rapidfuzz" >nul 2>&1
|
||||
"%CONDA_EXE%" run -n botty python -c "import cv2,mss,numpy,tesserocr,discord,transitions,rapidfuzz" >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo.
|
||||
echo WARNING: Dependency check failed. Running diagnostics...
|
||||
echo.
|
||||
"%PYTHON%" -c "import os,sys,ctypes;lb=os.path.join(sys.prefix,'Library','bin');dlls=[f for f in (os.listdir(lb) if os.path.isdir(lb) else []) if any(k in f.lower() for k in ['tess','lepton'])];print(' Tesseract DLLs in Library/bin:',dlls or 'NONE');d=[x for x in [os.path.join(sys.prefix,'Library',s) for s in ['bin','mingw-w64\\bin','usr\\bin']] if os.path.isdir(x)];[os.add_dll_directory(x) for x in d];f=ctypes.windll.kernel32.LoadLibraryExW;f.restype=ctypes.c_void_p;f.argtypes=[ctypes.c_wchar_p,ctypes.c_void_p,ctypes.c_ulong];t=os.path.join(lb,'tesseract51.dll');h=f(t,None,0x1000) if os.path.isfile(t) else None;print(' LoadLibraryExW tesseract51.dll:','OK' if h else 'FAILED');import tesserocr;print(' tesserocr import: OK')" 2>&1
|
||||
"%CONDA_EXE%" run -n botty python -c "import tesserocr; print(' tesserocr: OK')" 2>&1
|
||||
echo.
|
||||
echo *** Do NOT run "pip install tesserocr" manually - it builds from source and
|
||||
echo *** will always fail on Windows. Re-run install.bat to fix dependencies.
|
||||
|
||||
+19
-8
@@ -1,17 +1,28 @@
|
||||
@echo off
|
||||
setlocal
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
set "BOTTY_DIR=%~dp0"
|
||||
cd /d "%BOTTY_DIR%"
|
||||
|
||||
call "%BOTTY_DIR%find_python.bat"
|
||||
|
||||
:: Prepend conda DLL dirs to PATH at the process level so the Windows DLL
|
||||
:: loader finds tesseract51.dll's transitive deps (leptonica, zlib, etc.)
|
||||
:: when ctypes loads it. os.environ['PATH'] set from inside Python is too late.
|
||||
for %%F in ("%PYTHON%") do set "_CONDA_ENV=%%~dpF"
|
||||
set "_CONDA_ENV=%_CONDA_ENV:~0,-1%"
|
||||
set "PATH=%_CONDA_ENV%\Library\bin;%_CONDA_ENV%\Library\mingw-w64\bin;%_CONDA_ENV%\Library\usr\bin;%PATH%"
|
||||
:: Derive conda.exe from the botty python.exe path:
|
||||
:: envs\botty\python.exe -> envs\botty -> envs -> miniforge3 -> Scripts\conda.exe
|
||||
for %%F in ("%PYTHON%") do set "_ENV=%%~dpF"
|
||||
set "_ENV=%_ENV:~0,-1%"
|
||||
for %%F in ("%_ENV%") do set "_ENVS=%%~dpF"
|
||||
set "_ENVS=%_ENVS:~0,-1%"
|
||||
for %%F in ("%_ENVS%") do set "_ROOT=%%~dpF"
|
||||
set "_ROOT=%_ROOT:~0,-1%"
|
||||
set "_CONDA=%_ROOT%\Scripts\conda.exe"
|
||||
|
||||
echo Launching Botty ...
|
||||
%PYTHON% "%BOTTY_DIR%src\main.py"
|
||||
if exist "%_CONDA%" (
|
||||
:: conda run activates the full environment (PATH, DLL dirs, etc.)
|
||||
:: exactly like "conda activate botty" - guaranteed to find all DLLs.
|
||||
"%_CONDA%" run -n botty --no-capture-output python "%BOTTY_DIR%src\main.py"
|
||||
) else (
|
||||
echo WARNING: conda.exe not found at %_CONDA%, falling back to direct launch.
|
||||
"%PYTHON%" "%BOTTY_DIR%src\main.py"
|
||||
)
|
||||
pause
|
||||
|
||||
Reference in New Issue
Block a user