Convert long filename to short filename (8.3) using cmd.exe
Asked Answered
E

3

37

I am trying to convert a long filename to a short filename (8.3) on Windows.

A batch-file with a command line argument works as intended:

short.bat:

@echo OFF
echo %~s1

calling short.bat C:\Documents and Settings\User\NTUSER.DAT returns C:\DOCUM~1\USER\NTUSER.DAT

However, I don't like having an extra .bat-file for this. I would rather call cmd.exe with the whole command from a ruby script. How can I do this?

As an intermediate step I tried to hardcode the path in the batch-file, but that does not work:

short1.bat:

@echo OFF
SET filename="C:\Documents and Settings\User\NTUSER.DAT"
echo %filename%
echo %~sfilename%

echo %filename% works, but echo %~sfilename% gives the following error:

The following usage of the path operator in batch-parameter
substitution is invalid: %~sfilename%

For valid formats type CALL /? or FOR /?

If short1.bat works, how can I convert this into a one-liner that can be called with cmd.exe \c ...?

There is another question (how to get DOS path instead of Windows path), however that one is specifically asking for the path of the current directory.

Earthward answered 19/4, 2012 at 11:35 Comment(8)
I don't have Windows immediately handy, but try %filename:~s% (similar style to the substring notation, %filename:~0,1%). If that works, I'll make an answer of it.Sputnik
@ChrisMorgan - definitely not. Won't work.Ensanguine
@dbenham: no? ah well. It was worth a try.Sputnik
Why do you need the short name anyway? That's legacy functionality, best avoided unless absolutely necessary.Compressive
@HarryJohnston: a program that I wan't to start needs this special path names as it gets confused by the spaces in folder names.Earthward
Your best bet may be to copy the target file to the local file system.Compressive
Enclosing file names (or full paths) within quotes solves most problems that arise from spaces within names. Short names may not be necessary. If would have to be very old software to not support long file names.Ensanguine
@Ensanguine - long file names have to be in quotes, which can be tricky to pass into common routines such as psexec - see #24906046Visitant
E
52
cmd /c for %A in ("C:\Documents and Settings\User\NTUSER.DAT") do @echo %~sA
Ensanguine answered 19/4, 2012 at 12:8 Comment(10)
This works fine on my local drive, but not on a mapped network-drive. Any ideas?Earthward
@Earthward - What version of Windows are you using? There is a known XP bug dealing with 8.3 names and the ~s modifier: #8354805Ensanguine
@Earthward - Also, generation of 8.3 file names can be disabled for a given drive by the administrator. Can you verify that DIR /X gives short file names on your network drive?Ensanguine
I am using Windows XP, but the bug has nothing to do with it. It simply does not change the whole path at all. It seems to be, that this feature is disabled, as DIR \X does not give short file names. Is there any way around this?Earthward
@Earthward - I am fairly certain you are stuck, unless you can get your administrator to enable short file names on your network drives. But short names are probably disabled for a reason.Ensanguine
@dbenham: +1, short names are a monstrosity. They can cause all sorts of problems, especially in a server context.Compressive
If you are the administrator, you can enable short filenames by runing the following command at an elevated command prompt (without the quotes): "fsutil.exe behavior set disable8dot3 0"Stenography
Tried this from a batch file and it doesnt work! ... i tried also adding % at the end (%%~sA) ... but still doesn't work. However it works from cmdSearles
@AKhudairy - This question was specifically about a solution for the command line using cmd /c. Within a batch file you must double all percents - All you need is for %%A in ("some path here\some file.ext") do echo %%~sAEnsanguine
Not sure why, but this (as well as other answers here...) does not work for external (NTFS) drives on Win10, but only for the OS drive.Bernard
C
6

Replace the filename.txt to the filename you want to convert to 8.3

dir /x filename.txt

You will then have to split the result with whitespace as your delimiter (\s in regex). Then the value with the ~ is your short filename. If your filename is short to begin with, then you won't find a string containing a ~.

Commandant answered 19/4, 2012 at 12:3 Comment(1)
A rather inefficient way of doing it. Calling the batch script would be vastly more efficient, I would expect.Sputnik
M
0

Here is an example that read in the registry the location of your "appdata\local" folder and convert it to short path:

cls
@echo off
cd /d "%~dp0"
chcp 65001 >nul

for /f "skip=1" %%a in ('"wmic useraccount where name='%USERNAME%' get sid"') do (
    for %%b in (%%a) do set current_SID=%%b
)
set current_username=%USERNAME%
set current_userprofile=%USERPROFILE%

set key_to_read=HKEY_USERS\%current_SID%\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
set value_to_read=Local AppData
rem If value_to_read contains ? space(s) set tokens to 2+?
for /f "usebackq eol= tokens=3,* delims= " %%a in (`reg query "%key_to_read%" /v "%value_to_read%" 2^>nul ^| find "%value_to_read%"`) do (
    set value_type=%%a
    set data_read=%%b
)
set data_read=%data_read:USERPROFILE=current_userprofile%
call set "data_read=%data_read%"
set current_local_appdata=%data_read%

set current_local_appdata_temp=%current_local_appdata%\Temp
echo %current_local_appdata_temp%

for %%a in ("%current_local_appdata_temp%") do set "current_local_appdata_temp_short=%%~sa"
echo %current_local_appdata_temp_short%

pause
exit
Mechanistic answered 10/4, 2020 at 10:50 Comment(1)
Unfortunately your answer does not answer the question. Thus it might be deleted in the future. However, it might be useful for others. I would suggest that you ask a new question (even if you know the answer), and directly answer that question yourself.Earthward

© 2022 - 2024 — McMap. All rights reserved.