【问题标题】:How to get long filename from ARGV如何从 ARGV 获取长文件名
【发布时间】:2023-04-05 12:45:01
【问题描述】:

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

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

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

当我从命令行运行脚本时没有问题,使用长文件名作为参数。

使用拖放或发送到时如何获取长文件名?

【问题讨论】:

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


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

      我不知道是否可以更改您在拖放时收到的参数,但您可以使用 Win32 的 getLongPathName() 函数,使用 Ruby Win32 bindings

      --编辑--
      包括@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
      

      【讨论】:

      • varioustopics.com/ruby/518646-rre-ruby-cygwin-and-paths.html 上找到它需要'find' 需要'fileutils' 需要'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 get_long_win32_filename(a) end
      【解决方案3】:

      为了解决这个问题,我学到了很多东西!

      不过,@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"
      

      【讨论】:

        【解决方案4】:

        我找到了我的脚本收到短文件名的原因,我做了一个注册表补丁来启用 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}"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-11
          • 1970-01-01
          • 2019-02-11
          • 1970-01-01
          • 1970-01-01
          • 2014-12-02
          • 1970-01-01
          • 2011-09-25
          相关资源
          最近更新 更多