Convert long filename to short filename (8.3)
-
01-06-2021 - |
Question
I want to convert long filenames/path to short filenames (8.3). I'm developing a script that calls a command line tool that only accepts short filenames.
So i need to convert
C:\Ruby193\bin\test\New Text Document.txt
to
C:\Ruby193\bin\test\NEWTEX~1.TXT
So far i found How to get long filename from ARGV which uses WIN32API to convert short to long filenames (the opposite of what I want to achieve).
Is there any way to get the short filename in Ruby?
Solution 2
This ruby code uses getShortPathName and don't need additional modules to be installed.
def get_short_win32_filename(long_name)
require 'win32api'
win_func = Win32API.new("kernel32","GetShortPathName","PPL"," L")
buf = 0.chr * 256
buf[0..long_name.length-1] = long_name
win_func.call(long_name, buf, buf.length)
return buf.split(0.chr).first
end
OTHER TIPS
You can do this using FFI; there's actually an example that covers your exact scenario in their wiki under the heading "Convert a path to 8.3 style pathname":
require 'ffi'
module Win
extend FFI::Library
ffi_lib 'kernel32'
ffi_convention :stdcall
attach_function :path_to_8_3, :GetShortPathNameA, [:pointer, :pointer, :uint], :uint
end
out = FFI::MemoryPointer.new 256 # bytes
Win.path_to_8_3("c:\\program files", out, out.length)
p out.get_string # be careful, the path/file you convert to 8.3 must exist or this will be empty
The windows function you require is GetShortPathName. You could use that in the same manner as described in your linked post.
EDIT: sample usage of GetShortPathName (just as a quick example) - shortname will contain "C:\LONGFO~1\LONGFI~1.TXT" and returned value is 24.
TCHAR* longname = "C:\\long folder name\\long file name.txt";
TCHAR* shortname = new TCHAR[256];
GetShortPathName(longname,shortname,256);