What happens when a path has no directory separator? - windows

C:WProgram Files
Anyone knows such kind of location? How is it processed in programmes, the same as \ ?

A path with a drive letter and then a relative path is resolved relative to the current directory for that drive letter.
Windows and MS-DOS systems keep track of the current directory for each drive letter separately.
For example:
G:\>dir c:
Volume in drive C is System
Volume Serial Number is A09A-AD9C
Directory of C:\
06/12/2008 02:44 PM 0 AUTOEXEC.BAT
06/12/2008 02:44 PM 0 CONFIG.SYS
08/25/2008 02:22 PM <DIR> Documents and Settings
12/09/2009 12:45 PM <DIR> Program Files
[snip]
G:\>cd "c:\Program Files"
G:\>dir c:
Volume in drive C is System
Volume Serial Number is A09A-AD9C
Directory of C:\Program Files
12/09/2009 12:45 PM <DIR> .
12/09/2009 12:45 PM <DIR> ..
05/14/2010 11:38 AM <DIR> 7-Zip
12/13/2010 01:49 AM <DIR> Adobe
[snip]
G:\>dir c:Adobe
Volume in drive C is System
Volume Serial Number is A09A-AD9C
Directory of C:\Program Files\Adobe
12/13/2010 01:49 AM <DIR> .
12/13/2010 01:49 AM <DIR> ..
01/25/2010 01:45 AM <DIR> Reader 8.0
12/13/2010 01:49 AM <DIR> Reader 9.0
The path c:Adobe became the same as C:\Program Files\Adobe because that was the current directory for the C drive, even though the current drive was actually the G drive.

Related

creating mercurial repo in directory whose name has dollar signs

I am trying to create a mercurial repository in a directory whose name includes dollar signs. This is an equivalent and simplified example of what i get on windows 10 cmd.exe with mercurial 4.1.3 :
C:\test\dir1>hg init
C:\test\dir1>hg status
C:\test\dir1>cd ../dir$$1
C:\test\dir$$1>hg init
C:\test\dir$$1>hg status
abort: repository C:\test\dir$$1 not found!
so i hope this is clear, the only difference seems to be the dollar signs in the second directory name. thanks in advance!
Mercurial seems to treat dollar signs as an environment variable escape:
C:\test>set X=abc
C:\test>echo $X # Not the shell expanding it, that would be %X%.
$X
C:\test>hg init $X
C:\test>dir
Volume in drive C has no label.
Volume Serial Number is CE8B-D448
Directory of C:\test
11/10/2017 09:27 PM <DIR> .
11/10/2017 09:27 PM <DIR> ..
11/10/2017 09:27 PM <DIR> abc
0 File(s) 0 bytes
3 Dir(s) 53,899,231,232 bytes free
Mercurial has expanded $X as an environment variable. Also:
C:\test>hg init dir$$x
C:\test>dir
Volume in drive C has no label.
Volume Serial Number is CE8B-D448
Directory of C:\test
11/10/2017 09:30 PM <DIR> .
11/10/2017 09:30 PM <DIR> ..
11/10/2017 09:30 PM <DIR> dir$x
0 File(s) 0 bytes
3 Dir(s) 53,899,091,968 bytes free
Two dollar signs insert one dollar sign. When you are in a directory named dir$$x, Mercurial is using dir$x for the name. I found a workaround with hg -R. status, but better to avoid dollar signs.
this has been entered as a Mercurial bug : https://bz.mercurial-scm.org/show_bug.cgi?id=5739

Copy short 8.3 filename in long mode (Windows)

Trying to copy from command line a file named "SCOOTE~1.txt" to a folder where there is a file called "Scooter - Cosmos.txt".
The problem is that copy will contract the name of "Scooter - Cosmos.txt" to "Scoote~1.txt" as well and will ask if I want to overwrite that file.
How can I literally copy the "SCOOTE~1.txt" without affecting other long-named files ? Suggestion of external command-line tools is accepted.
Recreation of Problem
c:\Test> > "Scooter - Cosmos.txt" echo File with long name
c:\Test> md SFN
c:\Test> > "SFN\SCOOTE~1.TXT" echo File with short name
c:\Test> dir/s/x
Volume in drive C is OS
Volume Serial Number is BE3C-8BC1
Directory of c:\Test
22/09/2017 08:51 <DIR> .
22/09/2017 08:51 <DIR> ..
22/09/2017 08:50 21 SCOOTE~1.TXT Scooter - Cosmos.txt
22/09/2017 08:51 <DIR> Test
1 File(s) 21 bytes
Directory of c:\Test\SFN
22/09/2017 08:51 <DIR> .
22/09/2017 08:51 <DIR> ..
22/09/2017 08:51 22 SCOOTE~1.TXT
1 File(s) 22 bytes
Total Files Listed:
2 File(s) 43 bytes
5 Dir(s) 104,170,942,464 bytes free
Here the current directory has a file with a long-name of Scooter - Cosmos.txt and a short-name of SCOOTE~1.TXT (Note: the short-name is already in place at this stage). Also, the directory SFN contains a file called SCOOTE~1.TXT – because this name "fits" in the 8.3 format, it does not have a separate short-name.
If we now try to copy this file into the current directory, because the short-/only name of the file being copied matches the short-name of the file already present, it prompts about overwriting:
c:\Test> copy "SFN\SCOOTE~1.TXT"
Overwrite c:\Test\SCOOTE~1.TXT? (Yes/No/All): n
0 file(s) copied.
Single-Instance Fix
As eryksun suggested, you can use the fsutil file setshortname command to fix one-off clashes by changing the short-name of the file in the current directory:
c:\Test> fsutil file setshortname "Scooter - Cosmos.txt" SCOOTE~2.TXT
c:\Test> dir/x
Volume in drive C is OS
Volume Serial Number is BE3C-8BC1
Directory of c:\Test
22/09/2017 09:09 <DIR> .
22/09/2017 09:09 <DIR> ..
22/09/2017 08:50 21 SCOOTE~2.TXT Scooter - Cosmos.txt
22/09/2017 08:51 <DIR> SFN
1 File(s) 21 bytes
3 Dir(s) 104,168,501,248 bytes free
c:\Test> copy "SFN\SCOOTE~1.TXT"
1 file(s) copied.
c:\Test> dir/x
Volume in drive C is OS
Volume Serial Number is BE3C-8BC1
Directory of c:\Test
22/09/2017 09:09 <DIR> .
22/09/2017 09:09 <DIR> ..
22/09/2017 08:50 21 SCOOTE~2.TXT Scooter - Cosmos.txt
22/09/2017 08:51 22 SCOOTE~1.TXT
22/09/2017 08:51 <DIR> SFN
2 File(s) 43 bytes
3 Dir(s) 104,168,464,384 bytes free
Here we can see that the short-name of Scooter - Cosmos.txt has been changed so that it no longer clashes with SCOOTE~1.TXT; the copy proceeds with no warning and both files sit side-by-side in the current directory.
Multiple-Instance Fix
If there are (or could be) several clashes with the files in the target directory, an alternative approach is to use the fsutil 8dot3name strip command to remove the 8.3-format short-names from all files at once:
c:\Test> fsutil 8dot3name strip .
Scanning registry...
Total affected registry keys: 0
Stripping 8dot3 names...
Total files and directories scanned: 2
Total 8dot3 names found: 1
Total 8dot3 names stripped: 1
For details on the operations performed please see the log:
"C:\Users\xxxxxxxx\AppData\Local\Temp\8dot3_removal_log #(GMT 2017-09-22 08-36-00).log"
c:\Test> dir/x
Volume in drive C is OS
Volume Serial Number is BE3C-8BC1
Directory of c:\Test
22/09/2017 09:36 <DIR> .
22/09/2017 09:36 <DIR> ..
22/09/2017 08:50 21 Scooter - Cosmos.txt
22/09/2017 09:33 <DIR> SFN
1 File(s) 21 bytes
3 Dir(s) 104,154,349,568 bytes free
As can be seen, the file Scooter - Cosmos.txt no longer has a short-name, so there is no clash when SCOOTE~1.TXT is copied into the current directory:
c:\Test> copy "SFN\SCOOTE~1.TXT"
1 file(s) copied.
c:\Test> dir/x
Volume in drive C is OS
Volume Serial Number is BE3C-8BC1
Directory of c:\Test
22/09/2017 09:40 <DIR> .
22/09/2017 09:40 <DIR> ..
22/09/2017 08:50 21 Scooter - Cosmos.txt
22/09/2017 08:51 22 SCOOTE~1.TXT
22/09/2017 09:33 <DIR> SFN
2 File(s) 43 bytes
3 Dir(s) 104,151,703,552 bytes free
NOTE: The first stage of this command – Scanning registry... – may take some time as it is looking through the registry for references to the 8.3-format names that are about to be removed. See fsutil 8dot3name strip /? for more details of this command.
Caution (Applies to both methods)
As the help from the fsutil 8dot3name strip /? command says:
This command permanently removes 8dot3 file names from your volume. It
will list the registry keys pointing to the stripped 8dot3names but
will not modify the affected registry keys. Stripping will not be
performed on files with full path names longer than the maximum path
length of 260 characters.
both these commands modify (or remove) the 8.3-format names of selected files. If you have any references to the files concerned (either in the registry, configuration files, or elsewhere in .BAT files etc.) then these references will no longer be valid. Use either solution with due caution.

Strange behavior with dir "../*.*" (Note the forward slash)

Having the following folder structure:
A [Dir]
File.txt
B [Dir]
C [Dir]
Current working directory is at C
If I do
DIR "..\File.txt"
I get no files and that is expected since B is empty.
However if I do
DIR "../File.txt" --> Note the / instead of the \
I get the file at A !!!
If I do
DIR "../*.*"
I get the file at A and the dir output says the file is at B !!!
Here's the output of the DIR commands:
E:\a>dir
Directory of E:\a
2016-09-19 08:20 <DIR> .
2016-09-19 08:20 <DIR> ..
2016-09-19 08:20 5 File.txt
2016-09-19 08:19 <DIR> b
E:\a>cd b
E:\a\b>dir
Directory of E:\a\b
2016-09-19 08:19 <DIR> .
2016-09-19 08:19 <DIR> ..
2016-09-19 10:20 <DIR> c
E:\a\b>cd c
E:\a\b\c>dir
Directory of E:\a\b\c
2016-09-19 10:20 <DIR> .
2016-09-19 10:20 <DIR> ..
E:\a\b\c>dir "..\*.*"
Directory of E:\a\b
2016-09-19 08:19 <DIR> .
2016-09-19 08:19 <DIR> ..
2016-09-19 10:20 <DIR> c
E:\a\b\c>dir "../*.*"
Directory of E:\a\b
2016-09-19 08:20 <DIR> .
2016-09-19 08:20 <DIR> ..
2016-09-19 08:20 5 File.txt
2016-09-19 08:19 <DIR> b
Really strange. Is someone knowing what's happening?
Yes, there is an error in the dir tokenizer.
dir command will try to resolve the requested path+fileMask to a full directory path and then it will append the file mask (or asume a *) to enumerate the files inside the resolved path.
Curiously, the folder resolution has not any problem to determine what the starting folder should be (Directory of E:\a\b in your output), BUT the tokenizer has a problem removing the relative folder reference from the file mask when forward slashes are used.
The result is that once the folder is resolved to E:\a\b\ (correct), the full ../*.txt is appended (wrong part, the relative folder reference should have been separated from the file mask), and then E:\a\b\../*.txt is enumerated (that is, E:\a\*.txt) without any problem
Now, if we create a deeper hierarchy (E:\a\b\c\d), with d the current active directory, this behaviour can be tested by replacing the request to dir "../../*.txt". In this case, the starting folder will be resolved to
E:\a\b, but as the "../../*.txt" will be appended, at the end the root folder will be enumerated.
note: at this moment I don't have a debugger at hand to be 100% secure of this, but it has been tested running a cmd instance under Api Monitor and the api calls show the described behaviour.

Memory Usage of the c directory files in cmd

So, im running dir c:\ in command prompt and it shows me,
dir c:\
Volume in drive C is OS
Volume Serial Number is BE7A-83CF
Directory of c:\
12/06/2012 04:48 PM Accumedic
02/10/2016 10:27 AM 221,431 avgremover.log
12/23/2015 01:44 AM 3,072 Datacollectors.db
05/08/2012 05:45 PM DELL
02/18/2011 11:46 AM Drivers
02/02/2012 02:17 PM 23,760 FLBS1601.TEST
02/02/2012 02:29 PM 23,760 FLBS1602.TEST
02/18/2011 11:46 AM Install
02/06/2012 11:48 AM 22 Network.bat
07/13/2009 11:20 PM PerfLogs
02/01/2016 03:27 PM Program Files
10/14/2015 03:05 PM Program Files (x86)
12/27/2011 01:34 PM Projects
05/04/2016 08:52 AM SQL_Docs
04/07/2014 04:30 PM temp
07/23/2015 11:19 AM Users
05/04/2016 08:47 AM Windows
5 File(s) 272,045 bytes
12 Dir(s) 1,979,822,080 bytes free
Is there a command to see the disk usage of each of the files, instead of just the total? Preferably, in a similar format, and not individually looking each one up.
It is showing you the sizes of the files in the directory. From your question:
02/10/2016 10:27 AM 221,431 avgremover.log
12/23/2015 01:44 AM 3,072 Datacollectors.db
This is telling you that avgremover.log is 221,431 bytes in size. Most of the lines in your example don't have a number because they are directories. dir doesn't list a size for them.

Code to determine target of remote junction

Windows 7/NTFS and later has both symbolic links and junctions, and they are subtly different. (See this excellent set of posts). For logging (and debugging) purposes, I need to be able to resolve the target of a junction on a remote file server. There have been some posts on this topic, but they apply to resolving a junction as the local machine see it.
On \\FileServer, we have a directory G:\Shared that is shared out as PublicShare, so it apears on the network as \\FileServer\PublicShare. Within that directory are sub-directories G:\Shared\SubDir1 and G:\Shared\SubDir2. Also within that directory is a junction G:\Shared\Junc that points to either G:\Shared\SubDir1 or G:\Shared\SubDir2. (The target can change.) Thus, on \\FileServer, one sees
\\FileServer\PublicShare\SubDir1
\\FileServer\PublicShare\SubDir2
\\FileServer\PublicShare\Junc
On a client machine where \\FileServer\PublicShare is mounted (mapped in Windows lingo) as M:\, one thus sees M:\SubDir1, M:\SubDir2, M:\Junc. If, on that client machine, you open a console (cmd.exe) and do dir M:\, Windows gives a nice listing which shows that M:\Junc is a junction and includes the target, G:\Shared\SubDirX, of the junction.
M:\>dir
Volume in drive M is XXXXXXXXX
Volume Serial Number is XXXX-XXXX
Directory of M:\
09/05/2014 07:30 PM <DIR> .
09/05/2014 07:30 PM <DIR> ..
09/05/2014 01:36 PM <JUNCTION> Junc [G:\Shared\SubDir1]
09/06/2014 12:55 PM <DIR> SubDir1
09/05/2014 05:15 PM <DIR> SubDir2
0 File(s) 0 bytes
3 Dir(s) 1,895,493,492,736 bytes free
M:\>
Thus, the target of such a junction is clearly available to a client. Does anyone know how to obtain this information programatically, e.g. which system api to call??? Thanks.
This does the trick:
fsutil reparsepoint query "M:\Junc"
and it seems very reliable.
If you don't want to parse the output of C:\Windows\System32\fsutil.exe, you could simply use DIR:
for /f "usebackq delims=[] tokens=2" %i in ( `dir M:\^|findstr JUNCTION` ) do set RES=%i
Notes:
M:\: you need to display the subfolders (and junctions) of the parent folder of the JUNCTION (in this case: M:\)
findstr: if you have several junctions and want to resolve a specific one, add a |findstr foldername to isolate the right line,
delims=[]: that will divide the output 09/05/2014 01:36 PM <JUNCTION> Junc [G:\Shared\SubDir1] into 3 tokens:
09/05/2014 01:36 PM <JUNCTION> Junc
G:\Shared\SubDir1
"<empty>"
tokens=2: only the second token ("G:\Shared\SubDir1") is of interest
%i: if you run that command in a .bat script, double the '%': %%i in and res=%%i

Resources