What does %~dp0 mean, and how does it work?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
%~dp0 is a Windows batch file variable that expands to the drive letter and directory path of the currently running script. If your batch file lives at C:\Projects\deploy\run.bat, then %~dp0 evaluates to C:\Projects\deploy\. It always ends with a trailing backslash. This is the single most important variable for writing portable batch scripts that reference files relative to their own location.
Breaking Down the Syntax
The expression %~dp0 is built from three parts:
| Part | Meaning | Example |
%0 | The batch file itself (argument zero) | C:\Projects\deploy\run.bat |
~d | Extract the drive letter | C: |
~p | Extract the path (without drive, without filename) | \Projects\deploy\ |
Combined, ~dp gives you drive + path. The 0 refers to argument zero, which is always the script itself.
All available modifiers
Windows batch files support a full set of modifiers on any argument %0 through %9:
| Modifier | Expands to | Example (for C:\Projects\deploy\run.bat) |
%~0 | Full path with quotes removed | C:\Projects\deploy\run.bat |
%~f0 | Fully qualified path | C:\Projects\deploy\run.bat |
%~d0 | Drive letter only | C: |
%~p0 | Path only (no drive, no filename) | \Projects\deploy\ |
%~n0 | Filename without extension | run |
%~x0 | Extension only | .bat |
%~dp0 | Drive + path | C:\Projects\deploy\ |
%~nx0 | Filename + extension | run.bat |
%~dpnx0 | Full path (same as %~f0) | C:\Projects\deploy\run.bat |
%~z0 | File size in bytes | 1024 |
%~t0 | Date/time of file | 06/15/2026 02:30 PM |
%~a0 | File attributes | --a------ |
%~s0 | Short (8.3) path | C:\PROJEC~1\DEPLOY~1\run.bat |
You can look up this full list anytime by running call /? in a CMD window.
Practical Examples
Example 1: Run an executable next to the batch file
This launches myapp.exe from the same folder as the batch file, passing a config file also in that folder. It works regardless of what directory the user runs the script from.
Example 2: Set the working directory to the script location
The /d flag is important. Without it, cd cannot switch drives (e.g., from D: to C:).
Example 3: Reference a subfolder
Since %~dp0 always ends with \, appending tools\ gives you C:\Projects\deploy\tools\.
Example 4: Add the script directory to PATH temporarily
This prepends the bin subfolder to PATH for the duration of the script, making any executables in that folder available.
Example 5: Pass the script directory to a PowerShell command
Example 6: Log the script location for debugging
Output:
%~dp0 vs. %CD% vs. pushd/popd
These three approaches serve different purposes:
| Variable/Command | Returns | Changes when user cds? |
%~dp0 | Directory of the batch file | No (always the script location) |
%CD% | Current working directory | Yes |
pushd "%~dp0" | Sets CWD to script dir, saves previous | Yes (restores with popd) |
%CD% is where the user was when they ran the script. %~dp0 is where the script lives. They are often different:
If the user types C:\Users\alice> D:\scripts\deploy.bat, then %CD% is C:\Users\alice and %~dp0 is D:\scripts\.
Using pushd/popd for temporary directory changes
%~dp0 Inside Subroutines (CALL)
When you use CALL :label, %~dp0 still refers to the main script, not the subroutine. However, inside a CALLed external script, %~dp0 refers to that external script's location:
Output:
Quoting Rules
Always wrap %~dp0 in double quotes when using it in paths. Without quotes, paths containing spaces will break:
The Equivalent in PowerShell
PowerShell has its own variables for the same purpose:
| Batch | PowerShell | Description |
%~dp0 | $PSScriptRoot | Directory of the script |
%~f0 | $PSCommandPath | Full path of the script |
%~nx0 | Split-Path $PSCommandPath -Leaf | Filename of the script |
In Bash on Linux/macOS, the equivalent is:
Common Pitfalls
- Forgetting
/dwithcd.cd %~dp0does not change drives. If the script is onD:and the user is onC:, thecdwill silently fail. Always usecd /d "%~dp0". - Double backslash when appending. Since
%~dp0ends with\, writing%~dp0\subfolderproducesC:\Projects\\subfolder. This usually works in Windows but looks wrong. Omit the extra backslash:%~dp0subfolder. - Using
%~dp0insideFORloops. Inside aFORloop,%0may be rebound. If you need the script directory inside a loop, save it to a variable first:set SCRIPT_DIR=%~dp0. - UNC paths. If the script is on a network share (
\\server\share\script.bat),cd /d "%~dp0"will fail becausecddoes not support UNC paths. Usepushd "%~dp0"instead, which maps a temporary drive letter. - Delayed expansion confusion. If you use
enabledelayedexpansion, make sure you are not mixing!and%syntax when referencing%~dp0. The%~dp0variable is expanded at parse time, not at execution time, so it always uses%.
Summary
%~dp0returns the drive and directory path of the batch file that is currently running, always ending with a backslash.%0is the script itself,~dextracts the drive,~pextracts the path.- Always quote it:
"%~dp0"to handle spaces in paths. - Use
cd /d "%~dp0"to change the working directory to the script location (the/dflag enables cross-drive changes). - Use
pushd "%~dp0"for UNC network paths or when you want to restore the original directory later withpopd. - The PowerShell equivalent is
$PSScriptRoot. The Bash equivalent is$(cd "$(dirname "$0")" && pwd). - Run
call /?in CMD to see the full list of available modifiers.

