मैं win32-api library का उपयोग कर फ़ाइल संस्करण जानकारी प्राप्त करने के लिए मानक Win32 API फ़ंक्शंस को कॉल करने का प्रयास कर रहा हूं।रूबी win32api और structs (VerQueryValue)
3 version.dll फ़ंक्शन GetFileVersionInfoSize, GetFileVersionInfo, और VerQueryValue हैं। फिर मैं VS_FIXEDFILEINFO संरचना की एक प्रति प्राप्त करने के लिए kernel32.dll में RtlMoveMemory को कॉल करता हूं (माइक्रोसॉफ्ट प्रलेखन देखें: http://msdn.microsoft.com/en-us/library/ms646997%28VS.85%29.aspx
)।
मैंने एक उदाहरण से आकर्षित किया जिसे मैंने वीबी: http://support.microsoft.com/kb/139491
का उपयोग करके देखा था।
मेरी समस्या यह है कि अंततः लौटाया जाने वाला डेटा अपेक्षित संरचना से मेल नहीं खाता है, वास्तव में यह एक स्थिर मूल्य भी नहीं लौटाता है। मुझे संदेह है कि डेटा किसी बिंदु पर उलझ रहा है, शायद VerQueryValue या RtlMoveMemory में।
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.
मुझे लगता है कि मैं इसे समझ से बाहर .. मूल रूप से VerQueryValue एक सूचक (चर addr ऊपर) के लिए सूचक देता है, जबकि RtlMoveMemory एक सूचक चाहता है लंबे समय तक कि addr यानी, संदर्भ। RtlMoveMemory = Win32 :: API.new ('RtlMoveMemory', 'पीएलआई', 'वी', 'kernel32.dll') और फिर इसे बुला: RtlMoveMemory.call ( इसलिए मैं घोषणा बदल fixed_info, addr.unpack ('एल') [0], fixed_info.length) –