Преобразовать длинное имя файла в короткое имя файла (8.3)

Я хочу преобразовать длинные имена файлов / путь в короткие имена файлов (8.3). Я разрабатываю скрипт, который вызывает инструмент командной строки, который принимает только короткие имена файлов.

Так что мне нужно конвертировать

C:\Ruby193\bin\test\New Text Document.txt

в

C:\Ruby193\bin\test\NEWTEX~1.TXT

До сих пор я нашел, как получить длинное имя файла от ARGV, который использует WIN32API для преобразования коротких имен файлов в длинные (противоположность того, что я хочу достичь).

Есть ли способ получить короткое имя файла в Ruby?

3 ответа

Решение

Этот код ruby ​​использует getShortPathName и не требует установки дополнительных модулей.

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

Вы можете сделать это, используя FFI; на самом деле есть пример, который описывает ваш точный сценарий в их вики под заголовком "Преобразовать путь в 8.3 стиле":

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

Требуемая функция Windows - GetShortPathName. Вы можете использовать это так же, как описано в вашей ссылке.

РЕДАКТИРОВАТЬ: пример использования GetShortPathName (просто в качестве быстрого примера) - короткое имя будет содержать "C:\LONGFO~1\LONGFI~1.TXT", а возвращаемое значение равно 24.

TCHAR* longname = "C:\\long folder name\\long file name.txt";
TCHAR* shortname = new TCHAR[256];
GetShortPathName(longname,shortname,256);
Другие вопросы по тегам