From e1c18faf26fa9c91bbbe392f9eb84d0e983efe44 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 24 May 2026 14:37:14 +0200 Subject: [PATCH] fix: use conda run instead of direct python for DLL loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- install.bat | 14 ++++---------- run_botty.bat | 27 +++++++++++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/install.bat b/install.bat index fa3a716..483918f 100644 --- a/install.bat +++ b/install.bat @@ -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. diff --git a/run_botty.bat b/run_botty.bat index 1d867a4..943240f 100644 --- a/run_botty.bat +++ b/run_botty.bat @@ -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