What does %~d0 mean in a Windows batch file? - windows

I'm looking at a batch file which defines the following variables:
set _SCRIPT_DRIVE=%~d0
set _SCRIPT_PATH=%~p0
What do %~d0 or %~p0 actually mean?
Is there a set of well-known values for things like current directory, drive, parameters to a script?
Are there any other similar shortcuts I could use?

The magic variables %n contains the arguments used to invoke the file: %0 is the path to the bat-file itself, %1 is the first argument after, %2 is the second and so on.
Since the arguments are often file paths, there is some additional syntax to extract parts of the path. ~d is drive, ~p is the path (without drive), ~n is the file name. They can be combined so ~dp is drive+path.
%~dp0 is therefore pretty useful in a bat: it is the folder in which the executing bat file resides.
You can also get other kinds of meta info about the file: ~t is the timestamp, ~z is the size.
Look here for a reference for all command line commands. The tilde-magic codes are described under for.

They are enhanced variable substitutions. They modify the %N variables used in batch files. Quite useful if you're into batch programming in Windows.
%~I - expands %I removing any surrounding quotes ("")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string
You can find the above by running FOR /?.

Yes, There are other shortcuts that you can use which are given below.
In your command, ~d0 would mean the drive letter of the 0th argument.
~ expands the given variable
d gets the drive letter only
0 is the argument you are referencing
As the 0th argument is the script path, it gets the drive letter of the path for you. You can use the following shortcuts too.
%~1 - expands %1 removing any surrounding quotes (")
%~f1 - expands %1 to a fully qualified path name
%~d1 - expands %1 to a drive letter only
%~p1 - expands %1 to a path only
%~n1 - expands %1 to a file name only
%~x1 - expands %1 to a file extension only
%~s1 - expanded path contains short names only
%~a1 - expands %1 to file attributes
%~t1 - expands %1 to date/time of file
%~z1 - expands %1 to size of file
%~$PATH:1 - searches the directories listed in the PATH
environment variable and expands %1 to the fully
qualified name of the first one found. If the
environment variable name is not defined or the
file is not found by the search, then this
modifier expands to the empty string
%~dp1 - expands %1 to a drive letter and path only
%~nx1 - expands %1 to a file name and extension only
%~dp$PATH:1 - searches the directories listed in the PATH
environment variable for %1 and expands to the
drive letter and path of the first one found.
%~ftza1 - expands %1 to a DIR like output line
This can be also found directly in command prompt when you run CALL /? or FOR /?

From Filename parsing in batch file and more idioms - Real's How-to:
The path (without drive) where the script is : ~p0
The drive where the script is : ~d0

Another tip that would help a lot is that to set the current directory to a different drive one would have to use %~d0 first, then cd %~dp0. This will change the directory to the batch file's drive, then change to its folder.
For #oneLinerLovers, cd /d %~dp0 will change both the drive and directory :)
Hope this helps someone.

Some gotchas to watch out for:
If you double-click the batch file %0 will be surrounded by quotes. For example, if you save this file as c:\test.bat:
#echo %0
#pause
Double-clicking it will open a new command prompt with output:
"C:\test.bat"
But if you first open a command prompt and call it directly from that command prompt, %0 will refer to whatever you've typed. If you type test.batEnter, the output of %0 will have no quotes because you typed no quotes:
c:\>test.bat
test.bat
If you type testEnter, the output of %0 will have no extension too, because you typed no extension:
c:\>test
test
Same for tEsTEnter:
c:\>tEsT
tEsT
If you type "test"Enter, the output of %0 will have quotes (since you typed them) but no extension:
c:\>"test"
"test"
Lastly, if you type "C:\test.bat", the output would be exactly as though you've double clicked it:
c:\>"C:\test.bat"
"C:\test.bat"
Note that these are not all the possible values %0 can be because you can call the script from other folders:
c:\some_folder>/../teST.bAt
/../teST.bAt
All the examples shown above will also affect %~0, because the output of %~0 is simply the output of %0 minus quotes (if any).

%~d0 gives you the drive letter of argument 0 (the script name), %~p0 the path.

This code explains the use of the ~tilde character, which was the most confusing thing to me. Once I understood this, it makes things much easier to understand:
#ECHO off
SET "PATH=%~dp0;%PATH%"
ECHO %PATH%
ECHO.
CALL :testargs "these are days" "when the brave endure"
GOTO :pauseit
:testargs
SET ARGS=%~1;%~2;%1;%2
ECHO %ARGS%
ECHO.
exit /B 0
:pauseit
pause

It displays the current location of the file or directory that you are currently in. for example; if your batch file was in the desktop directory, then "%~dp0" would display the desktop directory. if you wanted it to display the current directory with the current file name you could type "%~dp0%~n0%~x0".

Related

Using cmd.exe in Registry Key Commands

I'm trying to write a context menu command (RCM). The command starts a program within the current folder that has a generic name, Alias.
This is what I've got to work so far.
cmd /c ""%0\alias.exe""
I've tried other forms like
"%0\alias.exe"
but it doesn't work. I feel it should work and that there is just a minor syntax error but can't fathom it. Any ideas?
You are using %0 which is in fact the name of your batch file.
You would need to use %~d0 (drive letter) combined with %~p0 (path)
So use %~dp0
It also already expands with the trailing \ so you can simply do:
"%~dp0alias"
For more, from cmd.exe help option call /?
%~1 - expands %1 removing any surrounding quotes (")
%~f1 - expands %1 to a fully qualified path name
%~d1 - expands %1 to a drive letter only
%~p1 - expands %1 to a path only
%~n1 - expands %1 to a file name only
%~x1 - expands %1 to a file extension only
%~s1 - expanded path contains short names only
%~a1 - expands %1 to file attributes
%~t1 - expands %1 to date/time of file
%~z1 - expands %1 to size of file
%~$PATH:1 - searches the directories listed in the PATH
environment variable and expands %1 to the fully
qualified name of the first one found. If the
environment variable name is not defined or the
file is not found by the search, then this
modifier expands to the empty string
%~dp1 - expands %1 to a drive letter and path only
%~nx1 - expands %1 to a file name and extension only
%~dp$PATH:1 - searches the directories listed in the PATH
environment variable for %1 and expands to the
drive letter and path of the first one found.
%~ftza1 - expands %1 to a DIR like output line
EDIT
As per previous believe that %0 is the path, it is not, it displays the batchfile name. Do this in a batch file and see the result:
#echo off
echo %0
echo %~0
echo %~n0
echo %dp0
echo %~dp0
pause
Then, why ""%~dp0\alias.exe"" works but "%~dp0\alias.exe" not.
cmd.exe consumes the first set of quotes. this is always the case.

CMD error filename/directory error

I used to program batch files for work but I quit since a long time, now I'm back on the job and there seemed to be a bit of a problem.
I try to edit txt files using CMD commands on a batch file:
e.g. echo hello >> *.txt
the thing is I want to add the text to all the txt files in that directory and I remember the * represented all the files in that directory with the same extension unless it's used as *.* then it includes all the files, but now all it does is just writes this error on cmd:
The filename, directory name, or volume label syntax is incorrect.
Can anyone can give a little help?
You can use a FOR /F loop with a DIR command to iterate the full paths and pass those over to the redirection append >> to echo to the text files accordingly.
Example FOR Loop
Be sure to change the value of the Folder= variable to be the directory you need to append to the files with the ECHO command.
Confirmed working batch script example
#ECHO ON
SET Folder=C:\MyFolder
CD /D "%Folder%"
FOR /F "TOKENS=*" %%A IN ('DIR /B /A-D "%Folder%\*.txt"') DO ECHO HELLO>>%%~fA
PAUSE
EXIT
Further Resources
DIR
FOR /F
In addition, substitution of FOR variable references has been
enhanced. You can now use the following optional syntax:
%~I - expands %I removing any surrounding quotes (")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string

Open cmd in folder without being in that folder

I want to create a shortcut,bat or exe that will open the command line in a specific folder within the current path the shortcut/bat/exe resides.
My example being the shortcut/bat/exe is located in
C:\Users\"user"\Desktop
I want to open the cmd in Folder
C:\Users\"user"\Desktop\Folder
But I don't want it to be dependent on the full path. I want to be able to move the exe and folder together to another location and it still work. So I want the exe to start cmd.exe in current path + \Folder
%windir%\system32\cmd.exe + \Folder
you could just put "cd folder" in the bat file.
exe would depend on what you use to create it, and don't know about shortcuts.
Also you can use %cd% in bat files to get current path.
C:\Users\user>echo %windir%\system32\cmd.exe %cd%\Folder
C:\Windows\system32\cmd.exe C:\Users\user\Folder
See call /? for a list of filenames/paths. This is in a batch not shortcut. %0 is the batchfile.
cd "%~dp0\folder"
Substitution of batch parameters (%n) has been enhanced. You can
now use the following optional syntax:
%~1 - expands %1 removing any surrounding quotes (")
%~f1 - expands %1 to a fully qualified path name
%~d1 - expands %1 to a drive letter only
%~p1 - expands %1 to a path only
%~n1 - expands %1 to a file name only
%~x1 - expands %1 to a file extension only
%~s1 - expanded path contains short names only
%~a1 - expands %1 to file attributes
%~t1 - expands %1 to date/time of file
%~z1 - expands %1 to size of file
%~$PATH:1 - searches the directories listed in the PATH
environment variable and expands %1 to the fully
qualified name of the first one found. If the
environment variable name is not defined or the
file is not found by the search, then this
modifier expands to the empty string
The modifiers can be combined to get compound results:
%~dp1 - expands %1 to a drive letter and path only
%~nx1 - expands %1 to a file name and extension only
%~dp$PATH:1 - searches the directories listed in the PATH
environment variable for %1 and expands to the
drive letter and path of the first one found.
%~ftza1 - expands %1 to a DIR like output line

Windows batch file starting directory when 'run as admin'

I have a batch file which is in a directory and must be run from there as well because it updates files within this directory.
This works perfectly fine, except when the user runs the batch file as administrator (required on Vista). Then the starting directory is C:\Windows\System32.
Is there any way to still be able to know from which directory the batch file was run?
I dont want the user to enter the directory manually.
Try to access the batch files path like this:
echo %~dp0
For more information see the following quote from the command for /? that describes how the above command works:
You can now use the following optional syntax:
%~I - expands %I removing any surrounding quotes (")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string
The modifiers can be combined to get compound results:
%~dpI - expands %I to a drive letter and path only
%~nxI - expands %I to a file name and extension only
%~fsI - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
environment variable for %I and expands to the
drive letter and path of the first one found.
%~ftzaI - expands %I to a DIR like output line
Better than cd is pushd which will
change drive letter if starting from D:\...
assign a drive letter if on a UNC network path
So pushd %~dp0 is good.
Good practice is then to call popd when done.
This should solve your problem by setting the working directory for the batch file back to the current directory:
Include these two lines at the top of your .bat script:
#setlocal enableextensions
#cd /d "%~dp0"
Found at: http://www.codeproject.com/Tips/119828/Running-a-bat-file-as-administrator-Correcting-cur
To fix this problem, include these two lines at the top of your .bat script:
#setlocal enableextensions
#cd /d "%~dp0"
I use:
cd %0..
at the beginning of the batch file to change directory to the directory where the batch file was started in.
-Mathew
#setlocal enableextensions
#cd /d "%~dp0"
You can CD directly from the file name by adding the parent (not tested in windows 8.x, but has worked "forever" as far as I can remember).
CD %FILENAME%\..
and CD will change drives as well using /D, which is shown above but not explicitly mentioned so might be missed.
CD /D %FILENAME%\..
(FOR /?
IF /?
SET /?
CALL /?
GOTO /?
all provide highly useful reading if you use cmd.exe, I reread them once in a while.)
A working solution here:
http://www.vistax64.com/vista-general/79849-run-administrator-changes-default-directory.html
FOR /F %%I IN ("%0") DO SET BATDIR=%%~dpI
ECHO The batch file is located in directory %BATDIR%

Finding out the file name of the running batch file

Inside a windows batch file I'd like to figure out what the fully qualified path name of this batch file is.
I have tried %0 but this does only gave me the typed command (e.g. just the file name without path or extension).
For your information,
You will need to enable command extends, which is not exists before Win 2000 (I don't know NT4)
SEE: cmd.exe /?
/E:ON Enable command extensions (see below)
/E:OFF Disable command extensions (see below)
command extensions is enabled by default on windows.
Another help I suggest to read is the FOR command.
It contains complete meaning for those flag.
SEE: for /? from cmd
In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:
%~I - expands %I removing any surrounding quotes (")
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only
%~sI - expanded path contains short names only
%~aI - expands %I to file attributes of file
%~tI - expands %I to date/time of file
%~zI - expands %I to size of file
%~$PATH:I - searches the directories listed in the PATH
environment variable and expands %I to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string
The modifiers can be combined to get compound results:
%~dpI - expands %I to a drive letter and path only
%~nxI - expands %I to a file name and extension only
%~fsI - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
environment variable for %I and expands to the
drive letter and path of the first one found.
%~ftzaI - expands %I to a DIR like output line
In the above examples %I and PATH can be replaced by other valid
values. The %~ syntax is terminated by a valid FOR variable name.
Picking upper case variable names like %I makes it more readable and
avoids confusion with the modifiers, which are not case sensitive.
echo %~f0
works for me.
see for /? from cmd and read about variable substitution.
%CD% gives the current directory.
%~dp0 will give you the directory the script is in.
IE: script in c:\folder, I call it from c:\otherfolder
%CD% = C:\otherfolder
%~dp0 = c:\folder
(I'm 99% sure I've got those the right way round, but not got windows to check on atm).
edit: and from there, using the one you've already got, you should be able to get the batch file name
%~f0
%~dpnx0
Either of the above gives the fully-qualified path. Enclose it in double quotes in case the path contains spaces.
Calling script FIRST.BAT:
call second.bat %0 parameter-a parameter-b
Called script SECOND.BAT:
echo The name of this called script should be "SECOND", proof: %~n0
echo The 1st parameter passed should be "FIRST", proof: %1
shift
echo The name of the calling script should be "FIRST", proof: %~n0
echo The 1st parameter should be "parameter-a", proof: %1

Resources