clases - manipulacion de archivos en ruby
Comprobando la versión del archivo en Ruby en Windows (5)
Para cualquier archivo, necesitaría descubrir en qué formato está el archivo, y luego abrir el archivo y leer los bytes necesarios para averiguar qué versión es el archivo. No hay API o método común para determinar una versión de archivo en Ruby.
Tenga en cuenta que sería más fácil si la versión del archivo estuviera en el nombre del archivo.
¿Hay alguna forma en Ruby para encontrar la versión de un archivo, específicamente un archivo .dll?
Para los EXE y DLL de Windows:
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
La parte ''unpack'' + regexp es un truco, la manera ''correcta'' es la API VerQueryValue, pero esto debería funcionar para la mayoría de los archivos. (Probablemente falla miserablemente en juegos de caracteres extendidos).
Si está trabajando en la plataforma de Microsoft, debería poder utilizar la API de Win32 en Ruby para llamar a GetFileVersionInfo (), que le devolverá la información que está buscando. http://msdn.microsoft.com/en-us/library/ms647003.aspx
¿Qué sucede si desea obtener la información de la versión con ruby, pero el código ruby no se está ejecutando en Windows?
Lo siguiente hace exactamente eso (teniendo en cuenta la misma advertencia extendida de juego de caracteres):
#!/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
A partir de Ruby 2.0, el módulo DL
está en desuso. Aquí hay una versión actualizada de la respuesta de AShelly, usando 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]