2008-09-16 11 views

risposta

1

Per qualsiasi file, è necessario scoprire in che formato si trova il file, quindi aprire il file e leggere i byte necessari per individuare la versione del file. Non esiste un'API o un metodo comune per determinare una versione del file in Ruby.

Si noti che sarebbe più semplice se la versione del file fosse nel nome del file.

12

Per Windows EXE e DLL:

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 

Il 'decomprimere' + parte regexp è un hack, il modo "corretto" è l'API VerQueryValue, ma questo dovrebbe funzionare per la maggior parte dei file. (probabilmente fallisce miseramente su set di caratteri estesi.)

5

Cosa succede se si desidera ottenere le informazioni sulla versione con ruby, ma il codice ruby ​​non è in esecuzione su Windows?

Quanto segue fa proprio questo (badare lo stesso avvertimento esteso set di caratteri):

#!/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

Come di Ruby 2.0, il modulo DL è deprecato. Ecco una versione aggiornata della risposta di AShelly, utilizzando 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]