Проблема с циклом for состоит в том, что он оставляет завершающий символ \ в конце строки. Это вызывает проблемы, если вы хотите получить dirname несколько раз. Возможно, вам нужно получить имя каталога, который является прародителем каталога, содержащего файл, а не просто родительский каталог. Простое использование метода for во второй раз приведет к удалению \ и не приведет к каталогу дедушки.
То есть вы не можете просто сделать следующее.
set filename=c:\1\2\3\t.txt
for %%F in ("%filename%") do set dirname=%%~dpF
for %%F in ("%dirname%") do set dirname=%%~dpF
Это установит dirname в "c: \ 1 \ 2 \ 3", а не в "c: \ 1 \ 2".
Следующая функция решает эту проблему, также удаляя завершающий символ \.
:dirname file varName
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET _dir=%~dp1
SET _dir=%_dir:~0,-1%
endlocal & set %2=%_dir%
GOTO :EOF
Это называется следующим образом.
set filename=c:\1\2\3\t.txt
call :dirname "%filename%" _dirname
call :dirname "%_dirname%" _dirname