Calling GetFileVersionInfo()

BlitzMax Forums/BlitzMax Programming/Calling GetFileVersionInfo()

SebHoll(Posted 2006) [#1]
Hi,

In my app I need to get the file version of DLLs and EXEs from around the computer. I know I need to use the following API commands:

GetFileVersionInfo()
GetFileVersionInfoSize()

... and I know they are in the "version.dll" which isn't referenced in any .a files in the BlitzMax\lib. I can't work out how to call them. I've tried using LoadLibraryA() and GetProcAddress() but I think I have messed up in changing the variable types. Could someone please write some code that would get the version no. of say, "explorer.exe", just as an example.

Thanks for your help


Seb


N(Posted 2006) [#2]
Get a copy of MinGW and link to libversion.a.

As for getting the version -- it's painful:
Import "-lversion"
Extern "OS"
    Function GetFileVersionInfoSizeW%( f$w, h% Var )
    Function GetFileVersionInfoW%( f$w, h%, dwlen%, data@ Ptr )
    Function VerQueryValueW%( data@ Ptr, sub$w, outp@ Ptr Var, size% Var )
End Extern

Local file$ = "C:\WINDOWS\explorer.exe"
Local h%
Local s% = GetFileVersionInfoSizeW( file, h )

Assert s>0,"Failed to get version data size"

Local data@[s]

Assert GetFileVersionInfoW( file, 0, s, data ),"Failed to get version info"

Local d@ Ptr
Local languages%
Local langData@ Ptr
Assert VerQueryValueW( data, "\VarFileInfo\Translation", langData, languages ), "Failed to get file version pointer"

For Local i% = 0 To (languages/4)-1
    Local lang$ = Hex(Int Ptr(langData)[i]).ToLower( )
    lang = lang[4..]+lang[..4] ' Swap the shorts around
    
    If Not VerQueryValueW( data, "\StringFileInfo\"+lang+"\FileVersion", d, s ) Then
        Print "Failed to get data"
        Continue
    EndIf
    
    If s = 0 Then
        Print "No data to read."
        Continue
    EndIf
    
    Print String.FromShorts( Short Ptr( d ), s )
Next

Input
End



SebHoll(Posted 2006) [#3]
Thanks Noel ;-) - you really are a born genius (dare I say it). I have spent the last few hours trying to work it out and never got anywhere with it.

While we are on the topic of referencing external DLLs, please could you answer a few questions:

1) What the difference between an API call with "A" and an API call with "W" on the end?
2) What does the "Ptr" functions do? (Something to do with variable pointers???) :P
3) What do the identifiers $z, $w, and @ do?
4) Finally, what does the Extern function actually do when you pass "Win32" or "OS" to it?

Thanks once again


Seb


N(Posted 2006) [#4]
A is standard 8-bit ASCII, W is unicode.

Ptr designates that a variable is a pointer.

$z is a null-terminated C string (byte array with a null character (0) to designate its end).
$w is a null-terminated unicode string (short array with a null character (0) to designate its end).
@ is the short way of saying that something has the type Byte. @@ is for shorts. The two are apparently undocumented as usual...

As far as I know, Extern "OS", when used under Windows, designates that the function is part of the normal Win32 API. Probably also designates that the functions use the stdcall calling convention, but I can't confirm that.

I'm not exactly sure how it operates under Linux and MacOS X, or if it even does anything at all under the two.


SebHoll(Posted 2006) [#5]
Cheers


Azathoth(Posted 2006) [#6]
You also need another way to test for fails if you're not compiling in debug mode because Assert gets ignored.


N(Posted 2006) [#7]
If results are zero then it's failed. Pretty simple, hence why Assert works in debug mode.


Azathoth(Posted 2006) [#8]
Unfortuantly not everyone wants to release programs that only works in debug mode.


N(Posted 2006) [#9]
Which is beside the point considering it's an example.