You are getting the correct value, but it has to go through another layer of parsing when you ECHO the value. An unquoted ^
is the batch escape character used to turn special characters like &
and |
that have meaning into simple literal characters. Whatever character follows an unquoted caret is escaped and the caret is consumed.
You would get the exact same result if you were to simply ECHO the string literal:
echo C:\one^two^^three^^^four^^^^carets\
yields
C:\onetwo^three^four^^carets\
You can protect the carets by quoting the string, but then you get the quotes in your ECHO result:
echo "%~dp0"
You can easily transfer the original value to an environment variable without consuming carets and prove it by using SET to look at the result:
@echo off
setlocal
set "myPath=%~dp0"
set myPath
If you want to ECHO just the value without quotes, you could use delayed expansion. This works because delayed expansion occurs after parsing of special characters:
@echo off
setlocal enableDelayedExpansion
set "myPath=%~dp0"
echo !myPath!
You could also get the same result by transferring the value to a FOR variable. Expansion of FOR variables also occurs after special character parsing:
@echo off
for %%A in ("%~dp0") do echo %%~A