Ruby練習貼02:Windowsで、ファイルのバージョン情報を取得


今日は日本のお客様からリクエストが来ました.
彼は私たちのプログラムのインストールディレクトリの下のすべてのファイルと、これらのファイルのバージョン情報を含むレポートがほしいです.
見てみると、インストールパスの下には何千ものファイルがあり、
この問題は人が決められないようで、ちょうどrubyスクリプトを書いた.
 
以下のブログではフォルダを巡る操作について説明します.
Ruby練習貼01:2つのフォルダを巡り、同じ名前のファイルと同じ内容のファイルを削除する
残りの問題は、ファイルのバージョン情報をどのように取得するかです.
(このファイルにバージョン情報が存在する場合、一般的にdll、exeファイルにはバージョン情報がありますが、txtこれらのファイルは一般的にはありません.)
 
この問題を解決するためにrubyのWin 32 APIを使用する必要がある.
参照できる接続は、第2の接続にWin 32 APIの他のいくつかの例が含まれている.
[email protected]
Microsoft Windows Support@Programming Ruby - The Pragmatic Programmer's Guide
Checking version of file in Ruby on Windows@stackoverflow
 
この問題を解決するスクリプトは、get_を呼び出します.バージョン関数は、そのファイルに対応するバージョン情報を直接返す.
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
otepad.exe' puts get_version target1 puts get_version target2 puts get_version target3

 
ルビーにはもう一つのgemがある
彼はWin 32 APIの代替品です.
彼らの違いは以下の接続を参考にすることができます.
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