How to get long filename from ARGV

后端 未结 4 1411
野性不改
野性不改 2020-12-18 02:59

I want to make a tool that takes some filenames as parameters, but when I use this code:

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

and

相关标签:
4条回答
  • 2020-12-18 03:43

    I don't know if it is possible to change the argument you recieve on a drag and drop, but you could use the Win32 getLongPathName() function, using the Ruby Win32 bindings

    --edit--
    Including @peter's solution formatted for readability:

    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
    
    0 讨论(0)
  • 2020-12-18 03:46

    I found the reason my script receaved short filenames, i had done a registry patch to enable the drag and drop on ruby scripts and schortcuts as follows

    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}"
    

    But it had to be the following for LONG filenames

    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}"
    
    0 讨论(0)
  • 2020-12-18 03:50

    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
    
    0 讨论(0)
  • 2020-12-18 03:56

    I learned a lot trying to figure this out!

    However, @peter beat me to it with a much simpler solution.

    Here is mine, in case someone finds it useful. file_get_long_name.rb

    I got the idea from: an archived vb-world.net article and converted it to 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"
    
    0 讨论(0)
提交回复
热议问题