Directory management in... batch files!
Ok, consider it the only way I found to look original: It's 2006 and you're reading about cmd.exe and batch files tricks ;-)
I usually use JScript WSH scripts to automate tasks but occasionally batch files simply remain the best choice. It's especially true when what you need to do mostly consist in running a sequence of command-line programs.
I recently wrote a set of batch files that run programs located in the same directory (or in sub-directories, or in sibling directories. Whatever.) and the data files they manipulate are also in this directory. Pretty straightforward : use no paths (or relative paths) when specifying the programs and files locations.
The problem is you assume that the current working directory (CWD) is the directory where your batch file is located.
How to make sure the current working directory is correctly set ?
One way is to invoke the batch files using a shortcut: You can set the directory in there.
Hmm... Not very general a solution! What I want is to be able to run the batch file by double-clicking it in Explorer or by typing its full path in a command prompt.
Let's look for something better, such as maybe batch files argument specifier %0. No, not good: It yields the name of the batch file but not the path.
Here's something better: %~dp0. This converts to the (drive and directory) path of the batch file. Kewl! We can now add this statement at the top of our batch file to set the current directory:
cd %~dp0Not bad. But there's still a problem: if you start from another drive, cd won't change the current drive letter. You'll want to use the /d (d stands for drive) to fix this issue:
cd /d %~dp0Note that %~dp0 contains a trailing backslash. Therefore, you can use it in such combinations
cd /d %~dp0MySubDirThis sets the CWD as sub-dir MySubDir of the directory where the batch file is located.
Did you receive a good education ?
If yes, you'll want to set the CWD back to its original value when you're done.
Solution1 (bad. Think of the mess when you have nested batch files.):
SET OriginalDir=%CD%%CD% is a pseudo environment variable that yields the curent directory.
cd /d %~dp0
cd /d %OriginalDir%
Solution 2 (Much nicer):
pushd %~dp0pushd pushes the CWD and switches to the specified one (including drive letter).
popd restores the previously pushed directory.
Neat! No temp environment variables. Works like a charm with nested batch files.
Nested batch files
Just a reminder: don't forget to use call to invoke a batch file from another one. The trap is that you don't have to use call to execute another batch. But if you don't, the rest of the caller file will not be executed :-(
Note to Self