Announcement

Collapse
No announcement yet.

File Version

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • File Version

    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?

  • #2
    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

    Comment


    • #3
      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


      • #4
        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


        • #5
          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


          • #6
            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


            • #7
              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


              • #8
                See bellow


                [This message has been edited by Semen Matusovski (edited August 11, 2000).]

                Comment


                • #9
                  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


                  • #10
                    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


                    • #11
                      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


                      • #12
                        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


                        • #13
                          Code:
                          Semen--
                                
                          If you could try Word 97's WINWORD.EXE, you'd find all of the strings 
                          (CompanyName through ProductName) coming in blank.
                             
                          Greg

                          [This message has been edited by Greg Turgeon (edited August 12, 2000).]

                          Comment


                          • #14
                            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


                            • #15
                              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


                              • #16
                                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


                                • #17
                                  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


                                  • #18
                                    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[]; 
                                    };
                                    and to retrieve all fields without VerQueryValue.
                                    Not so easy, but should work in any case.


                                    [This message has been edited by Semen Matusovski (edited August 13, 2000).]

                                    Comment


                                    • #19
                                      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


                                      • #20
                                        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

                                        Working...
                                        X