如何从ARGV获取长文件名

时间:2011-11-14 22:08:03

标签: ruby windows command-line drag-and-drop long-filenames

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

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作为参数。

当我使用拖放或发送到?

时,如何获取长文件名

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:4)

我不知道是否可以通过拖放更改您收到的参数,但您可以使用getLongPathName()

使用Win32 Ruby Win32 bindings函数

- edit--
包括为了可读性而格式化的@ 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

答案 2 :(得分:0)

我学到了很多东西试图解决这个问题!

然而,@ peter用更简单的解决方案打败了我。

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

我从以下方面得到了这样的想法:一篇存档的vb-world.net文章并将其转换为红宝石。

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"

答案 3 :(得分:0)

我找到了我的脚本收到短文件名的原因,我已经完成了一个注册表补丁,以便按照以下方式拖放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}"

但是对于LONG文件名

,它必须是以下内容
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}"