86

How can you get the directory of the script that was run and use it within the .cmd file?

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • 2
    possible duplicate of [How to get the path of the batch script in Windows?](http://stackoverflow.com/questions/3827567/how-to-get-the-path-of-the-batch-script-in-windows) – Celada Dec 24 '12 at 05:01

4 Answers4

155

This is equivalent to the path of the script:

%~dp0

This uses the batch parameter extension syntax. Parameter 0 is always the script itself.

If your script is stored at C:\example\script.bat, then %~dp0 evaluates to C:\example\.

ss64.com has more information about the parameter extension syntax. Here is the relevant excerpt:

You can get the value of any parameter using a % followed by it's numerical position on the command line.

[...]

When a parameter is used to supply a filename then the following extended syntax can be applied:

[...]

%~d1 Expand %1 to a Drive letter only - C:

[...]

%~p1 Expand %1 to a Path only e.g. \utils\ this includes a trailing \ which may be interpreted as an escape character by some commands.

[...]

The modifiers above can be combined:

%~dp1 Expand %1 to a drive letter and path only

[...]

You can get the pathname of the batch script itself with %0, parameter extensions can be applied to this so %~dp0 will return the Drive and Path to the batch script e.g. W:\scripts\

Community
  • 1
  • 1
Landon
  • 15,166
  • 12
  • 37
  • 30
  • Exactly what I needed. And I linked this anwser to my blog, as a reminder :) – Olivier H Jan 07 '13 at 14:58
  • Not sure if it is a bug/error in the quoted text, but in my script i need "%~d0" to get the drive letter! %~d1 is empty in my case. – fklappan Oct 16 '15 at 10:59
  • In my eyes/situation this is superior to the accepted answer. If you run a command line script "as Administrator" (right click on it) your script will be executed from Windows\system32. The accepted answer will NOT give you the script location, it will give you Windows\system32 again. I.e. THIS answer helps you fix that, you start your script with cd %~dp0 – Jaroslav Záruba Jun 19 '16 at 03:32
  • **ATTENTION!** %~dp0 will break if you change the directory with `cd /d` to another drive! – Smit Johnth Jan 16 '21 at 17:16
60

Raymond Chen has a few ideas:

https://devblogs.microsoft.com/oldnewthing/20050128-00/?p=36573

Quoted here in full because MSDN archives tend to be somewhat unreliable:

The easy way is to use the %CD% pseudo-variable. It expands to the current working directory.

set OLDDIR=%CD%
.. do stuff ..
chdir /d %OLDDIR% &rem restore current directory

(Of course, directory save/restore could more easily have been done with pushd/popd, but that's not the point here.)

The %CD% trick is handy even from the command line. For example, I often find myself in a directory where there's a file that I want to operate on but... oh, I need to chdir to some other directory in order to perform that operation.

set _=%CD%\curfile.txt
cd ... some other directory ...
somecommand args %_% args

(I like to use %_% as my scratch environment variable.)

Type SET /? to see the other pseudo-variables provided by the command processor.

Also the comments in the article are well worth scanning for example this one (via the WayBack Machine, since comments are gone from older articles):

http://blogs.msdn.com/oldnewthing/archive/2005/01/28/362565.aspx#362741

This covers the use of %~dp0:

If you want to know where the batch file lives: %~dp0

%0 is the name of the batch file. ~dp gives you the drive and path of the specified argument.

Richard Neish
  • 8,414
  • 4
  • 39
  • 69
Kev
  • 118,037
  • 53
  • 300
  • 385
  • 13
    This does not answer the question. %CD% gives the current directory, while what was asked was the directory of the script. – ketorin Oct 07 '08 at 11:58
  • 3
    **@ketorin:** This **DOES** answer the question. %CD% will change if the script itself change directory throughout it's usage (pushd/cd/..) but **%~dp0** will **NOT** change and always point to where the script is located. – Jay Sep 08 '09 at 17:18
  • -1 I can't tell if this answers the question or not. Can you show me an example? – Iain Samuel McLean Elder Jul 25 '13 at 16:01
  • 1
    @IainElder - you're probably right, I re-visited this answer a few days ago and wasn't too happy with it. The comments on Raymond Chen's blog, which I refer to, seem to have been blitzed by MS - so therein lie the dangers of answers that rely entirely on linked external sources. I did try to find some other material to back up my answer but it's so long ago in the mists of time now. Flagging for deletion. Thanks for tipping me over the edge with this one :) You don't happen to work for SkyScanner do you? – Kev Jul 25 '13 at 23:49
  • 1
    @Kev It's okay to refer to external sources if you copy the helpful part to Stack Overflow. I guess now it's too late! And yes, I have been known to lurk in the Skyscanner data center ;-) – Iain Samuel McLean Elder Jul 26 '13 at 13:51
  • **ATTENTION!** %~dp0 will break if you change the directory with `cd /d` to another drive! – Smit Johnth Jan 16 '21 at 17:16
0

This answer will also work if the batch file is invoked without an explicit path!

First the script determines if the batch file was called with a path. If that's the case that path is used. If not, the %path% is searched to find the batch file.

@echo off
setlocal enableextensions enabledelayedexpansion

for /f %%i in ('cd') do set CURDIR=%%i
set LAUNCHERPATH=%~dp0

if "%LAUNCHERPATH%" neq "%CURDIR%\" goto LAUNCHERPATHOK

set LIST=%PATH%

:ProcessList
for /f "tokens=1* delims=;" %%a in ("!LIST!") do ( 
  if "%%a" neq "" ( 
    set x=%%a
    IF EXIST "%%a%0.bat" GOTO FOUND1
    IF EXIST "%%a\%0.bat" GOTO FOUND0
    IF EXIST "%%a%0" GOTO FOUND1
    IF EXIST "%%a\%0" GOTO FOUND0
  )
  if "%%b" NEQ "" (
    set List=%%b
    goto :ProcessList
  )
)
exit 1

:FOUND0
set x=%x%\
:FOUND1
set LAUNCHERPATH=%x%

:LAUNCHERPATHOK

echo %LAUNCHERPATH%

Kudos also to dos batch iterate through a delimited string for parsing the path variable

bebbo
  • 2,830
  • 1
  • 32
  • 37
-1
for /F "eol= delims=~" %%d in ('CD') do set curdir=%%d

pushd %curdir%

Source

Alex. S.
  • 143,260
  • 19
  • 55
  • 62