2008-09-16 40 views

Trả lời

1

Đối với bất kỳ tệp nào, bạn cần khám phá định dạng của tệp, sau đó mở tệp và đọc các byte cần thiết để tìm ra phiên bản của tệp. Không có API hoặc phương thức chung để xác định phiên bản tệp trong Ruby.

Lưu ý rằng sẽ dễ dàng hơn nếu phiên bản tệp có trong tên tệp.

12

Đối với của Windows EXE và DLL của:

require "Win32API" 
FILENAME = "c:/ruby/bin/ruby.exe" #your filename here 
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] : '??' }" 
else 
    puts "No Version Info" 
end 

Các 'giải nén' + phần regexp là một hack, cách "đúng đắn" là API VerQueryValue, nhưng điều này sẽ làm việc cho hầu hết các tập tin. (có thể thất bại thảm hại trên các bộ ký tự mở rộng.)

5

Nếu bạn muốn nhận thông tin phiên bản bằng ruby, nhưng mã ruby ​​không chạy trên Windows?

Sau đây không chỉ là (lưu ý đến những cảnh báo tương tự charset mở rộng):

#!/usr/bin/ruby 

s = File.read(ARGV[0]) 
x = s.match(/F\0i\0l\0e\0V\0e\0r\0s\0i\0o\0n\0*(.*?)\0\0\0/) 

if x.class == MatchData 
    ver=x[1].gsub(/\0/,"") 
else 
    ver="No version" 
end 

puts ver 
3

Như của Ruby 2.0, module DL bị phản đối. Dưới đây là phiên bản cập nhật câu trả lời của AShelly, sử dụng Fiddle:

version_dll = Fiddle.dlopen('version.dll') 

s='' 
vsize = Fiddle::Function.new(version_dll['GetFileVersionInfoSize'], 
      [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], 
      Fiddle::TYPE_LONG).call(filename, s) 

raise 'Unable to determine the version number' unless vsize > 0 

result = ' '*vsize 
Fiddle::Function.new(version_dll['GetFileVersionInfo'], 
        [Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG, 
         Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP], 
     Fiddle::TYPE_VOIDP).call(filename, 0, vsize, result) 

rstring = result.unpack('v*').map{|s| s.chr if s<256}*'' 
r = /FileVersion..(.*?)\000/.match(rstring) 

puts r[1] 
Các vấn đề liên quan