我想将长文件名/路径转换为短文件名(8.3)。我正在开发一个脚本,它调用只接受短文件名的命令行工具。
所以我需要转换
C:\Ruby193\bin\test\New Text Document.txt
到
C:\Ruby193\bin\test\NEWTEX~1.TXT
到目前为止,我找到了如何从 ARGV 获取长文件名,它使用 WIN32API 将短文件名转换为长文件名(与我想要实现的相反)。
有没有办法在 Ruby 中获取短文件名?
我想将长文件名/路径转换为短文件名(8.3)。我正在开发一个脚本,它调用只接受短文件名的命令行工具。
所以我需要转换
C:\Ruby193\bin\test\New Text Document.txt
到
C:\Ruby193\bin\test\NEWTEX~1.TXT
到目前为止,我找到了如何从 ARGV 获取长文件名,它使用 WIN32API 将短文件名转换为长文件名(与我想要实现的相反)。
有没有办法在 Ruby 中获取短文件名?
您可以使用FFI执行此操作;实际上,在他们的 wiki标题“将路径转换为 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
此 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
您需要的 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);