Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NT file/path variables question

117 views
Skip to first unread message

Jim Speiser

unread,
Jul 25, 2002, 8:02:33 PM7/25/02
to
According to my puny understanding, the following command:
FOR %%G IN (%~sdp0) DO SET BASE=%%G
contained in a file called TESTING.CMD should result in:
SET BASE=C:\[path]\

Why, then, does it result in
SET BASE=C:\[path]\TESTING.CMD?

==JJS==

Clay Calvert

unread,
Jul 25, 2002, 8:12:17 PM7/25/02
to
On 25 Jul 2002 17:02:33 -0700, jimsp...@yahoo.com (Jim Speiser)
wrote:

It shouldn't. Have you tried simply:

echo %~sdp0

and then use:

SET BASE=%~sdp0

HTH

Clay Calvert
CCal...@Wanguru.com
Replace "W" with "L"

Phil Robyn

unread,
Jul 26, 2002, 12:03:07 AM7/26/02
to

This is an intriguing question. I think the %~s... (get short
filename, etc.) functionality doesn't work exactly as one might
expect. I made up an example where the name of the batch file
and the name of the subdirectory in which it resided were both
longer than 8.3. Here's what I came up with in playing around
to retrieve the path to the file, exclusive of the name of the
file itself, in short name format:

<Win2000> c:\cmd>"d:\junkdir\a long subdir\getbasepath.cmd"
shortname=d:\junkdir\ALONGS~1\GETBAS~1.CMD
base=d:\junkdir\ALONGS~1\

<Win2000> c:\cmd>rlist "d:\junkdir\a long subdir\getbasepath.cmd"
=====begin d:\junkdir\a long subdir\getbasepath.cmd====================
01. @echo off
02. set shortname=%~sf0
03. set shortname
04. call :length
05. call :back
06.
07. set base
08. goto :EOF
09.
10. :length
11. set S1=%shortname%
12. set length=0
13. :lloop
14. if not defined S1 goto :EOF
15. set S1=%S1:~1%
16. set /a length+=1
17. goto :lloop
18.
19. :back
20. set ptr=-1
21. :bloop
22. call set char=%%shortname:~%ptr%,1%%
23. if "%char%" EQU "\" goto :bpath
24. set /a ptr-=1
25. goto :bloop
26.
27. :bpath
28. set /a limit = length %ptr%
29. set /a limit+=1
30. call set base=%%shortname:~0,%limit%%%
31. goto :EOF
=====end d:\junkdir\a long subdir\getbasepath.cmd====================

--
U s e ' R e p l y - T o ' a d d r e s s o r
u n z i p ' F r o m ' t o s e n d m a i l

Phil Robyn

unread,
Jul 26, 2002, 1:21:03 AM7/26/02
to

OK, I thought about it while I was walking my dog. Here's
a simpler solution:

=====begin d:\junkdir\a long subdir\getbasepath.cmd====================

1. @echo off
2. set shortname=%~sf0
3. set shortname
4. call :bpp "%shortname%"
5. set base
6. goto :EOF
7. :bpp
8. set base=%~dp1
9. goto :EOF

Garry Deane

unread,
Jul 26, 2002, 4:38:34 AM7/26/02
to
On 25 Jul 2002 17:02:33 -0700, jimsp...@yahoo.com (Jim Speiser)
wrote:

>According to my puny understanding, the following command:

There is a bug in how Cmd truncates longfilename paths when using
%~spi. I've been aware of this in NT but on checking, I'm surprised to
find that this bug still exists in W2k/XP.

Basically the problem is that Cmd fails to adjust the length of the
string returned when converting from a LFN path to a SFN path. The SFN
path is converted correctly BUT the length of the string returned is
the same length as the original LFN path. This ends up returning extra
characters on the line corresponding to some or all of the file name.
It's a little difficult to explain clearly but take for example a file
called "c:\program files\testlongfilename.bat"

The LFN pathname length is 17 chars including the drive and final \
(c:\program files\). If you use 'echo %~sdp0' in the file, it returns

c:\PROGRA~1\testl

which is 17 characters long. Cmd forgot to adjust the string length to
the new 12 character length so includes the extra 5 characters from
the start of 'testlongfilename.bat'

You can work around this in a 2 step process:
1. Convert the LFN filename to a SFN filename
set SFN=%~sf0
2. Convert the SFN filename to a SFN pathname
for %%i in (%SFN%) do set SPN=%%~dspi

Or in your example, you can do the following:

for %%i in (%~sf0) do set base=%%~dspi

Here's a little demo:

:::::: testlongfilename.bat ::::::
@echo off
:: this fails
echo %~sdp0
:: this works
for %%i in (%~sf0) do echo %%~dspi
:::::::::::::::::::::::::::::::::::::::::::::

D:\temp>"c:\program files\testlongfilename"
c:\PROGRA~1\testl
c:\PROGRA~1\

D:\temp>"c:\program files\common files\testlongfilename"
c:\PROGRA~1\COMMON~1\testlongf
c:\PROGRA~1\COMMON~1\

Garry

Jim Speiser

unread,
Jul 26, 2002, 1:16:55 PM7/26/02
to
Garry Deane <garrydeane_at_yahoo.com.au> wrote in message news:<3d41032e...@192.168.0.2>...

Thank you, this worked. Why is it %%~dspi, vs. %~dspi?


==JJS==

Garry Deane

unread,
Jul 28, 2002, 2:27:16 AM7/28/02
to
On 26 Jul 2002 10:16:55 -0700, in alt.msdos.batch.nt you wrote:

>> :::::: testlongfilename.bat ::::::
>> @echo off
>> :: this fails
>> echo %~sdp0
>> :: this works
>> for %%i in (%~sf0) do echo %%~dspi
>> :::::::::::::::::::::::::::::::::::::::::::::
>

>Thank you, this worked. Why is it %%~dspi, vs. %~dspi?
>
>
>==JJS==

When referring to the replaceable parameters in a FOR command ("i" in
this case) you use %%i in a batch file. If you were typing the FOR
command on the command line, you'd just use %i.

Garry

0 new messages