It is neither a unique feature of CMD (in whole) nor in any way unique to AutoHotkey. The only part unique to CMD is that the CD command updates those environment variables. The actual implementation of resolving paths like "a:" and "a:b" is almost certainly in GetFullPathName or some underlying system function.
It doesn't seem to be documented explicitly but there are probably hints here and there. For instance,
When you call a command line program and pass it a path like "D:somefile.txt" while the actual working directory is on C:, how do you think that program will find the file? It wouldn't be very useful, and probably wouldn't meet the goals of the feature, if it only worked within CMD's own internal commands.
relative references involving other drives are interpreted starting at the root of those drives
What gave you that idea? Of course
if none of the special variables are set, each drive other than the "current" one will default to its root.
Another point of note is that shell-related functions (such as file dialogs) perform their own "strict" validation of paths which treat paths like "D:somefile.txt" as invalid, along with a bunch of other valid Win32 paths. (For instance, I think it is only recent that Explorer has allowed names beginning with a dot.)
Raymond Chen wrote:Win32 does not have the concept of a separate current directory for each drive
Either Raymond doesn't mean what you think, or he is mistaken (gasp!) or mispoke. He basically confirms there is such a thing as per-drive current directory in another post:
How do I get the current directory for a non-current drive? Why would he be posting code used to retrieve the per-drive current directory using the standard Set & GetCurrentDirectory functions if such a concept did not even exist within Win32?
As for whether AutoHotkey's support for the concept was intentional, I think Chris wasn't even aware that "C:" is not the same as "C:\" -
// v1.0.45.01: Since A_ScriptDir omits the trailing backslash for roots of drives (such as C:),
// and since that variable probably shouldn't be changed for backward compatibility, provide
// the missing backslash to allow SetWorkingDir %A_ScriptDir% (and others) to work as expected
// in the root of a drive.
The documentation for A_ScriptDir says "The final backslash is omitted (even for root directories)."
I noticed it in 2018;
// Update in 2018: The reason it wouldn't by default is that "C:" is actually a reference to the
// the current directory if it's on C: drive, otherwise a reference to the path contained by the
// env var "=C:". Similarly, "C:x" is a reference to "x" inside that directory.
// For details, see
https://blogs.msdn.microsoft.com/oldnewthing/20100506-00/?p=14133
// Although the override here creates inconsistency between SetWorkingDir and everything else
// that can accept "C:", it is most likely what the user wants, and now there's also backward-
// compatibility to consider since this workaround has been in place since 2006.
// v1.1.31.00: Add the slash up-front instead of attempting SetCurrentDirectory(_T("C:"))
// and comparing the result, since the comparison would always yield "not equal" due to either
// a trailing slash or the directory being incorrect.
When long path support was added in v1.1.31.00, it included some other fixes for bugs where Loop File misbehaved when given a path with a drive letter and no slash.
Other than what I've mentioned above, I don't think AutoHotkey has any specific allowances for per-drive working directories. Perhaps even what I've mentioned can't be considered such, as I think they are just as applicable when everything is on a single drive.
In case you missed the implication,
SetWorkingDir C: is equivalent to
SetWorkingDir C:\, whereas (probably) all other commands allow C: to be treated the standard Windows way, which would seem to depend on the
=C: environment variable (if one exists and the "real" current directory is on a different drive).
Fun fact: the environment variables aren't limited to letters of the alphabet.
Code: Select all
SetWorkingDir %A_WinDir% ; To ensure A_ScriptDir is not the working directory. Presumably A_WinDir != A_ScriptDir.
EnvSet `=?:, %A_ScriptDir%
Run notepad ?:%A_ScriptName%
(This could be done without AutoHotkey, but I'm not sure how to set the variables using CMD.)
Also, it seems that C:\Windows\notepad.exe is not the same as C:\Windows\System32\notepad.exe on my system. It's missing its icon.