Ruby练习贴02: 在Windows上, 取得文件的版本信息

今天日本的客户来了一个要求,

他想要一个报表, 包含我们程序安装目录下的所有文件, 以及这些文件的版本信息.

看了一下, 安装路径下共有上千个文件,

看来这个问题人是搞不定了, 正好写一个ruby脚本.

 

在下面这篇博客里面已经介绍了遍历文件夹的操作.

Ruby练习贴01: 遍历两个文件夹, 删除那些名字相同, 内容也相同的文件

所以剩下的问题就是如何取得一个文件的版本信息了

(如果这个文件存在版本信息的话, 一般dll, exe文件都有版本信息, 但是txt这些文件一般就都没有了.)

 

为了解决这个问题, 需要使用ruby的Win32API.

可以参考的连接有, 其中第二个连接中还包含Win32API的其他的一些例子:

Win32API@ruby-doc.org

Microsoft Windows Support@Programming Ruby - The Pragmatic Programmer's Guide

Checking version of file in Ruby on Windows@stackoverflow

 

解决这一问题的脚本如下, 调用get_version函数, 直接返回该文件所对应的版本信息.

require "Win32API"

def get_version (filename)
  s=""
  vsize = Win32API.new('version.dll', 'GetFileVersionInfoSize',['P', 'P'], 'L').call(filename, s)
  #p vsize
  if (vsize > 0)
    result = ' '*vsize
    Win32API.new('version.dll', 'GetFileVersionInfo',['P', 'L', 'L', 'P'], 'L').call(filename, 0, vsize, result)
    rstring = result.unpack('v*').map{|s| s.chr if s<256}*''
    r = /FileVersion..(.*?)\000/.match(rstring)
    #puts "FileVersion = #{r ? r[1] : '??' }"
    ver = r[1]
  else
    ver = ""
  end
end

target1 = 'C:\Program Files (x86)\Microsoft F#\v4.0\Fsc.exe'
target2 = 'C:\Windows\DirectX.log'
target3 = 'C:\Windows\notepad.exe'
puts get_version target1
puts get_version target2
puts get_version target3

 

Ruby还有这么一个gem, win32-api.

他是Win32API的一个替代品.

他们之间的区别可以参考下面的连接

http://rubydoc.info/gems/win32-api/1.4.8/frames

 

最后,贴出这个应用的完整代码,

遍历特定文件夹, 显示所有文件的相对文件名, 以及他们的版本信息.

require "fileutils"
require "pathname"
require "Win32API"

def get_version (filename)
  s=""
  vsize = Win32API.new('version.dll', 'GetFileVersionInfoSize',['P', 'P'], 'L').call(filename, s)
  #p vsize
  if (vsize > 0)
    result = ' '*vsize
    Win32API.new('version.dll', 'GetFileVersionInfo',['P', 'L', 'L', 'P'], 'L').call(filename, 0, vsize, result)
    rstring = result.unpack('v*').map{|s| s.chr if s<256}*''
    r = /FileVersion..(.*?)\000/.match(rstring)
    #puts "FileVersion = #{r ? r[1] : '??' }"
    ver = r[1]
  else
    ver = ""
  end
end


target_dir = "C:/Program Files (x86)/my-install-folder"
Dir.glob("#{target_dir}/**/*") do |item|
  next if File.directory? item
  relative_path = Pathname.new(item).relative_path_from(Pathname.new(target_dir))
  info = "#{relative_path}\t\t#{get_version item}"
  puts info
end

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值