Sto provando a chiamare le funzioni API Win32 standard per ottenere informazioni sulla versione del file, utilizzando lo win32-api library.ruby win32api & structs (VerQueryValue)
Le 3 funzioni version.dll sono GetFileVersionInfoSize, GetFileVersionInfo e VerQueryValue. Quindi chiamo RtlMoveMemory in kernel32.dll per ottenere una copia della struttura VS_FIXEDFILEINFO (consultare la documentazione Microsoft: http://msdn.microsoft.com/en-us/library/ms646997%28VS.85%29.aspx
).
Ho estratto da un esempio che ho visto utilizzando VB: http://support.microsoft.com/kb/139491
.
Il mio problema è che i dati che vengono finalmente restituiti non sembrano corrispondere alla struttura prevista, in effetti non restituiscono nemmeno un valore coerente. Ho il sospetto che i dati si stiano verificando a un certo punto, probabilmente in VerQueryValue o RtlMoveMemory.
Ecco il codice:
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.
penso ho capito .. fondamentalmente VerQueryValue restituisce un puntatore a un puntatore (l'addr variabili di cui sopra), mentre RtlMoveMemory vuole un puntatore, cioè il tempo che addr Riferimenti. così ho cambiato la dichiarazione: RtlMoveMemory = Win32 :: API.new ('RtlMoveMemory', 'PLI', 'V', 'kernel32.dll') e poi chiamandolo: RtlMoveMemory.call (fixed_info, addr.unpack ('L') [0], fixed_info.length) –