2012-04-19 156 views
3

我想将长文件名/路径转换为短文件名(8.3)。 我正在开发一个调用只接受短文件名的命令行工具的脚本。将长文件名转换为短文件名(8.3)

,所以我需要转换

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

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

到目前为止,我发现How to get long filename from 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 
1

您需要的窗口功能是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); 
+0

我没有设法将该代码调整到_GetShortPathName_。你是否熟悉这一点,并可以提供一个例子? – user1251007 2012-04-19 14:11:50

+1

在C++中添加了代码,不能帮助您使用Ruby代码,但我想这应该与Peter在您的链接帖子中的帖子中一样。请注意,通常您应该首先使用NULL作为短名称并将其作为大小0调用它。这将返回所需的大小,然后用适当的大小和分配的缓冲区再次调用它。 – msam 2012-04-19 14:45:59

+0

感谢您的代码,我终于设法将其移植到Ruby代码 - 请参阅我的回答 – user1251007 2012-04-20 10:40:13

3

你可以使用FFI执行此操作;实际上,有覆盖标题下their 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 
+0

+1感谢您的回答。虽然我不喜欢安装额外的模块。对不起,我没有在我的问题中提到过。 – user1251007 2012-04-20 10:32:34