Unexpected duplicate directory names after expanding `%~dp0` in a BAT file
This is a known bug/design deficiency within cmd.exe - %~dp0
and variants can give the wrong result if the path to the batch script was quoted.
There is a work-around. You can reliably get the value from within a CALLed subroutine (note that at least one modifier like ~d
, ~f
etc. must be used, else you get the subroutine :label
)
@echo off
setlocal
pushd %~dp0
echo From main fails: "%~dp0"
call :test
popd
exit /b
:test
echo From subroutine OK: "%~dp0"
-- SAMPLE OUTPUT --
d:\dir>"my files\test.bat"
From main fails: "d:\dir\my files\my files\"
From subroutine OK: "d:\dir\my files\"
As a workaround, store the directory up-front:
set "dir=%~dp0"
This is because %0
is really path-as-invoked (like argv
arg 0), so in your examples it's either "my files"\run.bat
or "my files\run.bat"
.
When you do %~dp0
, cmd.exe is building up the full path relative to the current directory and then extracting the parts you asked for.
After you pushd
, the 'full path' (%~f0
) is going to be either:
C:\dir\my files\my files\run.bat
C:\dir\my files\my files"\run.bat
... and then trim off the filename to get your results.