4

Default answer is %~dp0. And most times this will work fine. But there is a bug in cmd.exe which will prevent this from working correctly under certain circumstances if you use double quotes to call the batch. Double quotes are necessary if the name or path of the batch file contains spaces. So for convenience everybody adds double quotes on all filenames.

I struggled very long with this bug.

This example will show the bug: Create this batch file, name it "z z.cmd" and put it in a folder specified by %path% or f.ex. in C:\Windows.

@echo off
echo.%~x0.
echo.%~dpnx0.
goto :eof

Now open a command prompt (so now we are in C:\Windows\System32 or %HOMEPATH%, it doesn't matter) and call the batch by typing "z z" (including double quotes). This is the output:

.
C:\Windows\System32\z z.

As you can see the file extension cannot be determined and the path shown is from where the batch was called, NOT where the batch is located. Ok. Now we will call the batch by typing "z z.cmd". This is the output:

.cmd.
C:\Windows\System32\z z.

Now the file extension is right (of course!), but the path is still wrong. Ok. Now we will rename the batch to a name without spaces, rename it to "z.cmd". Call it by typing "z" (always with double quotes) This is the output:

.
C:\Windows\System32\z.

As you can see, even the name has no spaces, it will still show the wrong path and unknown extension. So what does actually work ? :-) Only this methods to call the batch will work correctly:

>z
>z.cmd
>"C:\Windows\z.cmd"

As everybody knows best practice is to always add double quotes to all filenames. So we will keep this. But I also want to call batch files located in %path% with no need of specifying the full path. AND my batch also needs to know where it is located. SO.... This is the very simple workaround I found:

Save this in "z z.cmd"

@echo off
call :getself
goto :eof

:getself
echo.%~x0.
echo.%~dpnx0.
goto :eof

Call it with "z z" -> output will be:

.cmd.
C:\Windows\z z.cmd.

As it should be ! This workaround will work always, no matter how you call the batch.

So we learn cmd.exe does not always give the correct file information. Only by performing a call cmd.exe will recalculate and give the correct file information, IF it has double quotes !

The other way of handling the issue is this %~$path:0. It will show the correct path, BUT ONLY if you add .cmd when calling the batch file. So if on the command prompt you just type "z z", it will not work. You have to type "z z.cmd".

Any comments on this ? IS it a bug or a feature ?

Compo
  • 36,585
  • 5
  • 27
  • 39
hippo
  • 41
  • 2
  • 1
    Wow! Thanks! You should put it into an answer to your own question (and accept it, too). Not only would it give you some extra rep, but would make it a lot more readable and immediately apparent that this is actually a solved problem, not just a question. (It's an encouraged good practice, too.) – Sz. Aug 23 '22 at 21:50

0 Answers0