Czy istnieje sposób w Ruby, aby znaleźć wersję pliku, w szczególności plik .dll?Sprawdzanie wersji pliku w Ruby na Windows
Odpowiedz
Dla każdego pliku należy sprawdzić, w jakim formacie znajduje się plik, a następnie otworzyć plik i odczytać potrzebne bajty, aby dowiedzieć się, jaka to wersja pliku. Nie ma API ani wspólnej metody ustalania wersji pliku w Ruby.
Należy pamiętać, że byłoby łatwiej, gdyby wersja pliku znajdowała się w nazwie pliku.
Jeśli pracujesz na platformie Microsoft, powinieneś być w stanie użyć API Win32 w Ruby, aby wywołać metodę GetFileVersionInfo(), która zwróci informacje, których szukasz. http://msdn.microsoft.com/en-us/library/ms647003.aspx
W systemie Windows EXE i 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
do 'rozpakowania' + część regexp jest hack, "właściwego" sposób jest API VerQueryValue, ale to powinno działać na większości plików. (prawdopodobnie nie udaje się marnie na rozszerzonych zestawach znaków).
Co zrobić, jeśli chcesz uzyskać informacje o wersji z ruby, ale kod ruby nie działa w systemie Windows?
Poniższa właśnie to robi (zważając na to samo ostrzeżenie rozszerzonego zestawu znaków):
#!/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
Jak Ruby 2.0, moduł DL
jest przestarzała. Poniżej znajduje się zaktualizowana wersja odpowiedzi AShelly'ego, korzystająca z 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]