如何从ARGV获得长文件名

我想制作一个将一些文件名作为参数的工具,但是当我使用这个代码时:

ARGV.each do|a| puts "Argument: #{a}" end 

我使用拖放或“发送到”在Windows中,我得到的短文件名。 所以像"C:\Ruby193\bin\test\New Text Document.txt"变成C:\Ruby193\bin\test\NEWTEX~1.TXT作为参数。

命令行运行脚本时,没有问题,以longfilenames作为参数。

当我使用拖放或发送时,如何获得长文件名

Solutions Collecting From Web of "如何从ARGV获得长文件名"

我不知道是否可以通过拖放来更改接收的参数,但是可以使用Win32 getLongPathName()函数,使用Ruby Win32绑定

– 编辑 –
包括@ peter的解决方案格式化为可读性:

 require 'find' require 'fileutils' require 'Win32API' def get_long_win32_filename(short_name) max_path = 1024 long_name = " " * max_path lfn_size = Win32API.new("kernel32", "GetLongPathName", ['P','P','L'],'L').call(short_name, long_name, max_path) return (1..max_path).include?(lfn_size) ? long_name[0..lfn_size-1] : short_name end ARGV.each do|a| puts a puts get_long_win32_filename(a) end 

http://www.varioustopics.com/ruby/518646-rre-ruby-cygwin-and-paths.html

 require 'find' require 'fileutils' require 'Win32API' def get_long_win32_filename(short_name) max_path = 1024 long_name = " " * max_path lfn_size = Win32API.new("kernel32", "GetLongPathName", ['P','P','L'],'L').call(short_name, long_name, max_path) return (1..max_path).include?(lfn_size) ? long_name[0..lfn_size-1] : short_name end ARGV.each do|a| puts a puts get_long_win32_filename(a) end 

我学到了很多,试图弄清楚这一点!

然而@peter用一个更简单的解决办法打败了我。

这是我的,以防有人发现它有用。 file_get_long_name.rb

我从中得到了这个想法:一个存档的vb-world.net文章,并将其转换为ruby。

 require 'win32ole' def get_long_filename(shortpath, fso = WIN32OLE.new("Scripting.FileSystemObject")) path = case when fso.FolderExists(shortpath) fso.GetFolder(fso.GetAbsolutePathName(shortpath)) when fso.FileExists(shortpath) fso.GetFile(fso.GetAbsolutePathName(shortpath)) else return nil end parts = path.Path.split(/\\/) working = fso.GetDrive(parts.shift).RootFolder longpath = working.Path parts.each do |part| temppath = fso.BuildPath(longpath, part) working = fso.GetFolder(longpath) if fso.FolderExists(temppath) working.SubFolders.each do |sub| longpath = fso.BuildPath(longpath, sub.Name) if part== sub.ShortName || part == sub.Name end elsif fso.FileExists(temppath) working.Files.each do |sub| longpath = fso.BuildPath(longpath, sub.Name) if part== sub.ShortName || part == sub.Name end end end longpath end fso = WIN32OLE.new("Scripting.FileSystemObject") short = "C:\\DOCUME~1\\jamal\\Desktop\\NEWTEX~1.TXT" long = get_long_filename(short, fso) p long # ==> "C:\\Documents and Settings\\jamal\\Desktop\\New Text Document.txt" 

我发现我的脚本接收短文件名的原因,我做了一个注册表补丁,使拖放ruby脚本和schortcuts如下

 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\rbfile\ShellEx\DropHandler] @="{86C86720-42A0-1069-A2E8-08002B30309D}" [HKEY_CLASSES_ROOT\rbwfile\ShellEx\DropHandler] @="{86C86720-42A0-1069-A2E8-08002B30309D}" [HKEY_CLASSES_ROOT\RubyFile\ShellEx\DropHandler] @="{86C86720-42A0-1069-A2E8-08002B30309D}" [HKEY_CLASSES_ROOT\RubyWFile\ShellEx\DropHandler] @="{86C86720-42A0-1069-A2E8-08002B30309D}" 

但是,它必须是以下长文件名

 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\rbfile\ShellEx\DropHandler] @="{60254CA5-953B-11CF-8C96-00AA00B8708C}" [HKEY_CLASSES_ROOT\rbwfile\ShellEx\DropHandler] @="{60254CA5-953B-11CF-8C96-00AA00B8708C}" [HKEY_CLASSES_ROOT\RubyFile\ShellEx\DropHandler] @="{60254CA5-953B-11CF-8C96-00AA00B8708C}" [HKEY_CLASSES_ROOT\RubyWFile\ShellEx\DropHandler] @="{60254CA5-953B-11CF-8C96-00AA00B8708C}"