win32-api library'u kullanarak dosya sürümü bilgilerini almak için standart Win32 API işlevlerini çağırmaya çalışıyorum.ruby win32api & structs (VerQueryValue)
3 version.dll işlevleri GetFileVersionInfoSize, GetFileVersionInfo ve VerQueryValue'dir. Sonra VS_FIXEDFILEINFO yapısının bir kopyasını almak için kernel32.dll dosyasında RtlMoveMemory'yi çağırıyorum (bkz. Microsoft belgeleri: http://msdn.microsoft.com/en-us/library/ms646997%28VS.85%29.aspx
).
VB: http://support.microsoft.com/kb/139491
kullanarak gördüm bir örnekten çizdim.
Sorunum, sonunda döndürülen verilerin beklenen yapıyla eşleşmiyor gibi görünmesi, aslında tutarlı bir değer bile getirmiyor olmasıdır. Veriler bir noktada, muhtemelen VerQueryValue veya RtlMoveMemory'de karıştırıldığından şüpheleniyorum.
GetFileVersionInfoSize = Win32::API.new('GetFileVersionInfoSize','PP','I','version.dll')
GetFileVersionInfo = Win32::API.new('GetFileVersionInfo','PIIP','I', 'version.dll')
VerQueryValue = Win32::API.new('VerQueryValue','PPPP','I', 'version.dll')
RtlMoveMemory = Win32::API.new('RtlMoveMemory', 'PPI', 'V', 'kernel32.dll')
buf = [0].pack('L')
version_size = GetFileVersionInfoSize.call(myfile + "\0", buf)
raise Exception.new if version_size == 0 #TODO
version_info = 0.chr * version_size
version_ok = GetFileVersionInfo.call(file, 0, version_size, version_info)
raise Exception.new if version_ok == 0 #TODO
addr = [0].pack('L')
size = [0].pack('L')
query_ok = VerQueryValue.call(version_info, "\\\0", addr, size)
raise Exception.new if query_ok == 0 #TODO
# note that at this point, size == 4 -- is that right?
fixed_info = Array.new(13,0).pack('L*')
RtlMoveMemory.call(fixed_info, addr, fixed_info.length)
# fixed_info.unpack('L*') #=> seemingly random data, usually only the first two dwords' worth and the rest 0.
RtlMoveMemory bir işaretçi isterken temelde VerQueryValue o addr uzun yani, bir işaretçi (yukarıdaki değişken addr) bir gösterici ile döner:
FileVersion
ve doğru olarakProductVersion
Alma şu şekilde görünecektir Referanslar. RtlMoveMemory = Win32 :: API.new ('RtlMoveMemory', 'PLI', 'V', 'kernel32.dll') ve sonra çağırarak: RtlMoveMemory.call ( Yani deklarasyon değişti fixed_info, addr.unpack ('L') [0], sabit_info.length) –