0

I have some Python code, developed for Linux, from a repository that I would prefer not to change. The code uses the subprocess Python module to call a command line tool named colmap.

To get this code working under Windows, I installed colmap, added the bin folder containing colmap.exe to the PATH as well as the parent folder which contains the file COLMAP.bat. I then also had to change the Python code to run colmap.bat instead of colmap via subprocess.run.
The latter step I would like to avoid, as it would make the Python code incompatible with Linux/Mac and I would like to avoid adding an OS check via platform.system().

Is there a way to add colmap.exe to the PATH, so that it can be called via colmap by cmd.exe?

Like I said, the bin folder is already on the PATH. I already unsuccessfully tried to create a shortcut to COLMAP.bat with the name colmap as well as renaming COLMAP.bat to colmap.

This is the content of the batch file:

set SCRIPT_PATH=%~dp0

set PATH=%SCRIPT_PATH%\lib;%PATH%
set QT_PLUGIN_PATH=%SCRIPT_PATH%\lib\plugins;%QT_PLUGIN_PATH%

set COMMAND=%1
set ARGUMENTS=
shift
:extract_argument_loop
if "%1"=="" goto after_extract_argument_loop
set ARGUMENTS=%ARGUMENTS% %1
shift
goto extract_argument_loop
:after_extract_argument_loop

if "%COMMAND%"=="" set COMMAND=gui

"%SCRIPT_PATH%\bin\colmap" %COMMAND% %ARGUMENTS%
Mofi
  • 46,139
  • 17
  • 80
  • 143
user1323995
  • 1,286
  • 1
  • 10
  • 16
  • 1
    Please read first [What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?](https://stackoverflow.com/a/41461002/3074564) It explains in full details how the default shell interpreter `cmd.exe` on Windows searches for the file specified with just the file name like `colmap`. If __system__ or __user__ `PATH` and so finally __local__ `PATH` contains first the directory containing `colmap.bat`, there can be used just `colmap` in Python script file in the arguments of `subprocess.run` with `shell=True`. – Mofi Jul 05 '22 at 16:20
  • The directory `bin` of `colmap` does not need to be included in `PATH` at all if the batch file `colmap.bat` is improved to work really in any use case. The first command line in the batch file `colmap.bat` should be `@echo off` and the second line `setlocal EnableExtensions DisableDelayedExpansion` to define completely the required execution environment. The third line should be the first line posted by you modified to `set "SCRIPT_PATH=%~dp0"` to work even for `colmap` installed into a directory of which path contains by chance the character `&`. – Mofi Jul 05 '22 at 16:24
  • The next two lines should be `set "PATH=%SCRIPT_PATH%lib;%PATH%"` and `set "QT_PLUGIN_PATH=%SCRIPT_PATH%lib\plugins;%QT_PLUGIN_PATH%"`. Please read my answer on [Why is no string output with 'echo %var%' after using 'set var = text' on command line?](https://stackoverflow.com/a/26388460/3074564) It explains the reason for using `"` on environment variable definition exactly as used here required on `colmap` installed for example into `C:\Temp\Development & Test(!)_100%\Colmap`. – Mofi Jul 05 '22 at 16:26
  • Please note further that `%~dp0` expands to a directory path __always__ ending with ``\``. Therefore the environment variable `SCRIPT_PATH` is defined with a directory path ending already with a backslash. For that reason the concatenation with a folder name like `lib` must be done without using an additional backslash for a 100% directory path which does not need to be corrected by the Windows file I/O API functions on usage later by `cmd.exe` and `colmap.exe`. – Mofi Jul 05 '22 at 16:31
  • `set COMMAND=%1` should be modified to `set "COMMAND=%~1"` or the batch file will not work later on running `colmap.bat` is called with first argument enclosed in `"` like `"gui"` because of definition of the environment variable `COMMAND` with the value `"gui"` (yes, with the double quotes) resulting in `if "%COMMAND%"=="" set COMMAND=gui` expanding to `if ""gui""=="" set COMMAND=gui` which is causing a syntax error. `if "%1"=="" goto after_extract_argument_loop` should be modified to `if "%~1" == "" goto after_extract_argument_loop` to work also for arguments enclosed in `"`. – Mofi Jul 05 '22 at 16:33
  • I suggest to modify `if "%COMMAND%"=="" set COMMAND=gui` to `if "%COMMAND%" == "" set "COMMAND=gui"` which defines `COMMAND` even on running `colmap.bat` with first argument being `""` (empty argument string). I suppose that the other arguments are never empty argument strings as otherwise the condition posted above would need to be extended to support also empty argument strings. – Mofi Jul 05 '22 at 16:37
  • The last posted line `"%SCRIPT_PATH%\bin\colmap" %COMMAND% %ARGUMENTS%` should be modified to `"%SCRIPT_PATH%bin\colmap.exe" "%COMMAND%" %ARGUMENTS%` whereby the `"` around `%COMMAND%` are perhaps not needed although it is better to have them. The last line of the batch file should be `endlocal` for completeness although `cmd.exe` runs implicit `endlocal` before exiting the processing of the batch file. – Mofi Jul 05 '22 at 16:39

1 Answers1

1
if "%COMMAND%"=="" set COMMAND=gui

set "colmapexe="
for /f "delims=" %%b in ('where colmap.exe') do if not defined colmapexe set "colmapexe=%%b"

if defined colmapexe ("%colmapexe" %COMMAND% %ARGUMENTS%) else echo Colmap.exe not found&pause

should work by locating colmap.exe and installing it in the variable colmapexe

Magoo
  • 77,302
  • 8
  • 62
  • 84