I like to read out the File Version from an EXE or DLL file. With VB it's no problem, but how does it work in PB?
Announcement
Collapse
No announcement yet.
File Version
Collapse
X
-
This is easily accomplished with a resource file.
Include the following (edited with your data of course) in a resource file.
Compile and convert to a pbr and include it in your application..
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 5, 0, 0
PRODUCTVERSION 1, 5, 0, 0
FILEOS VOS_WINDOWS16
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", "Catalyst Systems, Inc.\000"
VALUE "FileDescription", "DSL/Cable Monitor\000"
VALUE "FileVersion", "00.50.0022\000"
VALUE "InternalName", "DSLM\000"
VALUE "OriginalFilename", "DSLM.EXE\000"
VALUE "LegalCopyright", "Copyright © 1999 Catalyst Systems, Inc.\000"
VALUE "LegalTrademarks", "Trademarks are property of respective owners\000"
VALUE "ProductName", "DSL Monitor for 9x/NT\000"
VALUE "ProductVersion", "00.50.0000\000"
VALUE "Comments", "Connection Monitor\000"
VALUE "PrivateBuild", " NONE \0"
VALUE "SpecialBuild", " Alpha Test\0"
END
END
END
Paul
-
Thanks Paul, but that don't answer my question.
Do include a version information via a resource file is clear.
What I want to know is, how to read out this information form a file via
GetFileInfoSize
GetFileInfo
VerQueryValue
and MemCopy.
I tried to take this code from VB (where it works fine) but it doesn't work.
Wolfgang
Comment
-
Search the source code forum, I posted example code there months ago.
--Dave
-------------
PowerBASIC Support
mailto:[email protected][email protected]</A>
Home of the BASIC Gurus
www.basicguru.com
Comment
-
Wolfgang,
Did you get any solution for your problem?
I cannot find anything in the Source Code Forum in respect with VerQueryValue. I think Dave means his sample code to retrieve the version numbers of the system (i.e. Windows). Wolfgang and I need to extract file version info from any EXE or DLL.
To be more specific: by a program, so not via the properties Dialog!
Can somebody help? And Wolf, if you have found a working solution in the meantime, please release it here or in the Source Code Forum.
Thanks for any help in advance,
[email protected]
------------------
[This message has been edited by Egbert Zijlema (edited August 10, 2000).]
Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
http://zijlema.basicguru.eu
*** Opinions expressed here are not necessarily untrue ***
Comment
-
Hi there,
Last month I wrote a small PBDLL app which runs like a command
line program (thanks to various people on how to code this...).
This returns the version info of a specified file, and uses
the VerQueryValue API.
I also had problems translating it from VB to PB, i.e. PB kept
on generating GPF's. I think it was to do with the way the
results to read from the API.
If you want the source code,just email me and I'll send it
to whoever wants it.
Dorian.
[email protected]
------------------
Comment
-
try some of the code in the following threads: (i searched for "verqueryval")
http://www.powerbasic.com/support/fo...-4-000651.html
http://www.powerbasic.com/support/pb...ad.php?t=17538
------------------
lance
powerbasic support
mailto:[email protected][email protected]</a>Lance
mailto:[email protected]
Comment
-
Code:Semen-- I was about to post my own version of this particular exercise, but I discovered something that affects your version too. Try out your code with $FileName = "PBEDIT.EXE" (the editor that comes with PBDLL 6.0). And try it (if you can) with Word97's WINWORD.EXE. Greg
-- Greg
[email protected]
Comment
-
Greg --
I see. Should be default value for language (040904E4)
Code:#Compile Exe #Register None #Dim All #Include "WIN32API.INC" $FileName = "C:\PbDll60\Bin\PbEdit.Exe" ' <------------ CHANGE Global VS_lpudtVerBuffer As VS_FIXEDFILEINFO Ptr Global VS_Buffer As String Global VS_Block As String Global VS_VerLanguage As Asciiz * 256 Function VS_MakeVersionS (Dg As Dword) As String Function = Format$(HiWrd(Dg)) + "." + Format$(LoWrd(Dg)) End Function Function VS_MakeVersionD (Dg1 As Dword, Dg2 As Dword) As String Local sTemp As String sTemp = Format$(HiWrd(Dg1)) + "." + Format$(LoWrd(Dg1), "00") + "." If HiWrd(Dg2) > 0 Then _ sTemp = sTemp + Format$(HiWrd(Dg2), "0000") + "." Function = sTemp + Format$(LoWrd(Dg2), "0000") End Function Function VS_StrucVersion As String Function = VS_MakeVersionS(@VS_lpudtVerBuffer.dwStrucVersion) End Function Function VS_FileVersion As String Function = VS_MakeVersionD(@VS_lpudtVerBuffer.dwFileVersionMS, _ @VS_lpudtVerBuffer.dwFileVersionLS) End Function Function VS_ProductVersion As String Function = VS_MakeVersionD(@VS_lpudtVerBuffer.dwProductVersionMS, _ @VS_lpudtVerBuffer.dwProductVersionLS) End Function Function VS_FileFlags As String Local FileFlags As String If @VS_lpudtVerBuffer.dwFileFlags And %VS_FF_DEBUG Then _ FileFlags = "Debug " If @VS_lpudtVerBuffer.dwFileFlags And %VS_FF_PRERELEASE Then _ FileFlags = FileFlags & "PreRel " If @VS_lpudtVerBuffer.dwFileFlags And %VS_FF_PATCHED Then _ FileFlags = FileFlags & "Patched " If @VS_lpudtVerBuffer.dwFileFlags And %VS_FF_PRIVATEBUILD Then _ FileFlags = FileFlags & "Private " If @VS_lpudtVerBuffer.dwFileFlags And %VS_FF_INFOINFERRED Then _ FileFlags = FileFlags & "Info " If @VS_lpudtVerBuffer.dwFileFlags And %VS_FF_SPECIALBUILD Then _ FileFlags = FileFlags & "Special " If @VS_lpudtVerBuffer.dwFileFlags And %VFT2_UNKNOWN Then _ FileFlags = FileFlags + "Unknown " Function = Trim$(FileFlags) End Function Function VS_FileOS As String Select Case @VS_lpudtVerBuffer.dwFileOS Case %VOS_DOS_WINDOWS16: Function = "DOS-Win16" Case %VOS_DOS_WINDOWS32: Function = "DOS-Win32" Case %VOS_OS216_PM16 : Function = "OS/2-16 PM-16" Case %VOS_OS232_PM32 : Function = "OS/2-16 PM-32" Case %VOS_NT_WINDOWS32 : Function = "NT-Win32" Case Else : Function = "Unknown" End Select End Function Function VS_FileType As String Local FileType As String, FileSubType As String Select Case @VS_lpudtVerBuffer.dwFileType Case %VFT_APP : FileType = "Application" Case %VFT_DLL : FileType = "DLL" Case %VFT_DRV : FileType = "Driver" Select Case @VS_lpudtVerBuffer.dwFileSubtype Case %VFT2_DRV_PRINTER : FileSubType = "Printer drv" Case %VFT2_DRV_KEYBOARD : FileSubType = "Keyboard drv" Case %VFT2_DRV_LANGUAGE : FileSubType = "Language drv" Case %VFT2_DRV_DISPLAY : FileSubType = "Display drv" Case %VFT2_DRV_MOUSE : FileSubType = "Mouse drv" Case %VFT2_DRV_NETWORK : FileSubType = "Network drv" Case %VFT2_DRV_SYSTEM : FileSubType = "System drv" Case %VFT2_DRV_INSTALLABLE : FileSubType = "Installable" Case %VFT2_DRV_SOUND : FileSubType = "Sound drv" Case %VFT2_DRV_COMM : FileSubType = "Comm drv" Case %VFT2_UNKNOWN : FileSubType = "Unknown" End Select Case %VFT_FONT : FileType = "Font" Select Case @VS_lpudtVerBuffer.dwFileSubtype Case %VFT2_FONT_RASTER : FileSubType = "Raster Font" Case %VFT2_FONT_VECTOR : FileSubType = "Vector Font" Case %VFT2_FONT_TRUETYPE : FileSubType = "TrueType Font" End Select Case %VFT_VXD : FileType = "VxD" Case %VFT_STATIC_LIB : FileType = "Lib" Case Else : FileType = "Unknown" End Select If FileSubType = "" Then Function = FileType Else _ Function = FileType + ", " + FileSubType End Function Function VS_StringInfo (Request As Asciiz) As String Dim lpBuffer As Asciiz Ptr, i As Long If VerQueryValue (ByVal StrPtr(VS_Buffer), VS_Block + Request, _ lpBuffer, i) Then If i Then Function = @lpBuffer End Function Function CollectVersionInfo (PathName As Asciiz) As Long VS_Buffer = "": VS_Block = "": VS_VerLanguage = "" Dim sTemp As String, i As Long, j As Dword i = GetFileVersionInfoSize(PathName, 0&) If i Then Function = %True Else Exit Function VS_Buffer = Space$(i) GetFileVersionInfo PathName, 0&, i, ByVal StrPtr(VS_Buffer) VerQueryValue ByVal StrPtr(VS_Buffer), "\", VS_lpudtVerBuffer, i sTemp = "040904E4" If VerQueryValue(ByVal StrPtr(VS_Buffer), "\VarFileInfo\Translation", j, i) Then If i Then sTemp = Peek$(j, i) sTemp = Hex$(Asc(sTemp, 2), 2) + Hex$(Asc(sTemp, 1), 2) + _ Hex$(Asc(sTemp, 4), 2) + Hex$(Asc(sTemp, 3), 2) End If End If VS_Block = "\StringFileInfo\" + sTemp + "\" VerLanguageName Val("&H" + Left$(sTemp, 4)), VS_VerLanguage, SizeOf(VS_VerLanguage) End Function Function PbMain() As Long If CollectVersionInfo ($FileName) Then MsgBox _ "StrucVersion = " + VS_StrucVersion + $CRLF + _ "File Version = " + VS_FileVersion + $CRLF + _ "Product Version = " + VS_ProductVersion + $CRLF + _ "FileOS = " + VS_FileOS + $CRLF + _ "FileType = " + VS_FileType + $CRLF + _ "FileFlags = " + VS_FileFlags + $CRLF + _ "Language = " + VS_VerLanguage + $CRLF + _ "CompanyName = " + VS_StringInfo ("CompanyName") + $CRLF + _ "FileDescription = " + VS_StringInfo ("FileDescription")+ $CRLF + _ "FileVersion = " + VS_StringInfo ("FileVersion") + $CRLF + _ "InternalName = " + VS_StringInfo ("InternalName") + $CRLF + _ "LegalCopyright = " + VS_StringInfo ("LegalCopyright") + $CRLF + _ "LegalTrademarks =" + VS_StringInfo ("LegalTrademarks") + $CRLF + _ "OriginalFilename = " + VS_StringInfo ("OriginalFilename") + $CRLF + _ "ProductName = " + VS_StringInfo ("ProductName"), , _ "Version Info for " + $FileName End Function
Comment
-
Okay,
Semen discovered already what went wrong.
Only one thing is still going wrong: From PBEDIT his program extracts zero as binary version number. Should be 6. How come?
------------------
[This message has been edited by Egbert Zijlema (edited August 12, 2000).]
Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
http://zijlema.basicguru.eu
*** Opinions expressed here are not necessarily untrue ***
Comment
-
Egbert --
Typically, file version is included twice (look Paul's sample):
1) As binary - FILEVERSION statement
2) As string - VALUE "FileVersion", "00.50.0022\000"
If you will test a code, posted above, you will see that programs extracts 0 in binary part.
Meanwhile as string - 06.00.0000
If you will test by Explorer, you will see the same.
This means that in resource file was described VALUE "FileVersion" only.
------------------
Comment
-
Greg --
I haven't English Word97. In Russian release there are no problems.
Pls, find another sample, which is possible to download or define resource file.
And, pls, test - Explorer sees well this info ?
PS. Theoretically it possible to read info directly w/o VerQueryValue.
I will analyze this possibillity. Somewhere should be description, how RC stores data.
------------------
Comment
-
Code:Semen-- Yes, Explorer displays the info & all strings correctly. I'll see if I can find another easily accessible file that illustrates what's happening. Here's what I know for sure, however. With WINWORD.EXE, VerQueryValue returns true from retrieving \VarFileInfo\Translation. If you then create the translation key, any attempt to use the key will fail and return false. Examining a dump of the version resource data in WINWORD.EXE, I can see that the language/charset translation value stored as a string is correct, but the binary version (which is the one returned through \VarFileInfo\Translation) is not complete. The character set field is correct and matches the string (04E4), but the language field is empty--two zero bytes. Greg
[This message has been edited by Greg Turgeon (edited August 12, 2000).]
Comment
-
Greg --
I found a sample in MSDN, how to enumerate languages and code pages.
But I need "incorrect" files.
Code:// Structure used to store enumerated languages and code pages. struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate; // Read the list of languages and code pages. VerQueryValue(pBlock, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate); // Read the file description for each language and code page. for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ ) { wsprintf( SubBlock, TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"), lpTranslate[i].wLanguage, lpTranslate[i].wCodePage); // Retrieve file description for language and code page "i". VerQueryValue(pBlock, SubBlock, &lpBuffer, &dwBytes); }
[This message has been edited by Semen Matusovski (edited August 13, 2000).]
Comment
-
Code:Semen-- I've seen this MSDN info as well. However: struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate; In the case of that uncooperative WINWORD.EXE, the wLanguage field returns filled with two zero bytes. That's why VerQueryValue fails when trying to retrieve the strings. Greg
------------------
-- Greg
[email protected]
Comment
-
Greg --
I played a little and found that occurs problem even in following case:
if to use RC-compiler with Paul's sample.
Try to change 040904E4 to something else (for example, "04191251") .
\VarFileInfo\Translation doesn't exist.
If to read with \StringFileInfo\04191251\ all strings will be visible.
PS. I reread MSDN. More or less clear, how Explorer can see not full structures.
It's necessary to follow MSDN description
Code:struct VS_VERSIONINFO { WORD wLength; WORD wValueLength; WORD wType; WCHAR szKey[]; WORD Padding1[]; VS_FIXEDFILEINFO Value; WORD Padding2[]; WORD Children[]; }; struct StringFileInfo { WORD wLength; WORD wValueLength; WORD wType; WCHAR szKey[]; WORD Padding[]; StringTable Children[]; };
Not so easy, but should work in any case.
[This message has been edited by Semen Matusovski (edited August 13, 2000).]
Comment
-
please see my code for accessing file version strings, its at...
http://www.powerbasic.com/support/pb...ad.php?t=23519
please post any comments here, thanks.
------------------
kev g peel
kgp software
bridgwater, uk.
mailto:[email protected][email protected]</a>
Comment
-
moved to: http://www.powerbasic.com/support/pb...ad.php?t=22778
[this message has been edited by egbert zijlema (edited august 20, 2000).]
Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
http://zijlema.basicguru.eu
*** Opinions expressed here are not necessarily untrue ***
Comment
Comment