Solved

Get File version info.

Posted on 2006-07-12
6
390 Views
Last Modified: 2010-04-05
Hi.

I need a small working code to retrieve some version information for a file.
I've searched EE database and saw some answers but the code is big and some times doesnt work.

Thanks in advance :)
0
Comment
Question by:CodedK
6 Comments
 
LVL 3

Expert Comment

by:jpedef
ID: 17090054
This piece of code should work

const
  InfoNum = 10;
  InfoStr: array[1..InfoNum] of string = ('CompanyName',
  'FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright',
  'LegalTradeMarks', 'OriginalFileName', 'ProductName', 'ProductVersion', 'Comments');

function GetFileVersionString(AFileName: string): string;
var
  VerStr: string;
  n, Len: DWORD;
  Buf: PChar;
  Value: PChar;
begin
  n := GetFileVersionInfoSize(PChar(AFileName), n);
  if n > 0 then
  begin
    Buf := AllocMem(n);
    try
      GetFileVersionInfo(PChar(AFileName), 0, n, Buf);
      if VerQueryValue(Buf, PChar('\StringFileInfo\040B04E4\FileVersion'), Pointer(Value), Len) then
        VerStr := 'Version: ' + Value
      else
        VerStr := 'Unknown version ';
    finally
      FreeMem(Buf);
    end;
  end
  else
    VerStr := 'No version information available';
  Result := VerStr;
end;
0
 
LVL 16

Author Comment

by:CodedK
ID: 17090244
Hi jpedef, thanks.

There is a problem with the code...
It shows 'no version info available' for files that have a version string.

I use it like this :
GetFileVersionString(Path of exe + exefilename)

How can i get the other strings like "comments","FileDescription","Company" etc ?
0
 
LVL 4

Expert Comment

by:kenpem
ID: 17090497
Try this one:
function getVersion : string;                         // poached from the online documentation
const    NOVIDATA = '';
var
  dwInfoSize,           // Size of VERSIONINFO structure
  dwVerSize,            // Size of Version Info Data
  dwWnd: DWORD;         // Handle for the size call.
  FI: PVSFixedFileInfo; // Delphi structure; see WINDOWS.PAS
  ptrVerBuf: Pointer;   // pointer to a version buffer
  strFileName,          // Name of the file to check
  strVersion : string;  // Holds parsed version number
begin
   strFileName := paramStr( 0 );
   dwInfoSize := getFileVersionInfoSize( pChar( strFileName ), dwWnd);
   if ( dwInfoSize = 0 ) then
      result := NOVIDATA
   else
     begin
       getMem( ptrVerBuf, dwInfoSize );
       try
         if getFileVersionInfo(pChar(strFileName),dwWnd,dwInfoSize,ptrVerBuf) and verQueryValue(ptrVerBuf,'\',pointer(FI),dwVerSize) then
           strVersion := format('%d.%d.%d.%d',[hiWord(FI.dwFileVersionMS),loWord(FI.dwFileVersionMS),
                       hiWord(FI.dwFileVersionLS),loWord(FI.dwFileVersionLS)]);
       finally
         freeMem( ptrVerBuf );
       end;
     end;
  Result := strVersion;
end;
0
Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

 
LVL 26

Accepted Solution

by:
Russell Libby earned 250 total points
ID: 17090534
The problem is that the code does not take into account the language translation tables that the file was built with, eg on my system I would need to use:

\StringFileInfo\040904B0\{value}

The following code (modified from above) makes use of the lang translation tables to return the desired values.

Russell

---


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

const
  InfoNum           = 10;
  InfoStr:          Array [1..InfoNum] of String =
                    (
                       'CompanyName',
                       'FileDescription',
                       'FileVersion',
                       'InternalName',
                       'LegalCopyright',
                       'LegalTradeMarks',
                       'OriginalFileName',
                       'ProductName',
                       'ProductVersion',
                       'Comments'
                    );

type
  TLangCharset      =  Array [0..1] of Word;
  PLangCharsets     =  ^TLangCharsets;
  TLangCharsets     =  Array [0..MaxWord] of TLangCharset;

function GetFileInfoString(FileName: String; Info: Integer): String;
var  dwSize:        DWORD;
     dwLength:      DWORD;
     dwIndex:       Integer;
     lpszBuffer:    PChar;
     lpCharset:     PLangCharsets;
     lpValue:       Pointer;
     wTemp:         Word;
begin

  // Clear result
  SetLength(result, 0);

  // Get file version info size
  dwSize:=GetFileVersionInfoSize(PChar(FileName), dwLength);

  // Check result
  if (dwSize > 0) then
  begin
     // Allocate memory
     lpszBuffer:=AllocMem(dwSize);
     try
        // Get file version info
        if GetFileVersionInfo(PChar(FileName), 0, dwSize, lpszBuffer) then
        begin
           // Query for the translation table so we know what lang-charset is being used
           if VerQueryValue(lpszBuffer, '\VarFileInfo\Translation', lpValue, dwLength) and (dwLength >= SizeOf(TLangCharset)) then
           begin
              // Get the language charset array
              lpCharset:=lpValue;
              // Calculate the number of items in the array
              dwSize:=dwLength div SizeOf(TLangCharset);
              // Walk the charsets
              for dwIndex:=0 to Pred(dwSize) do
              begin
                 // Get the desired info string
                 if VerQueryValue(lpszBuffer, PChar('\StringFileInfo\'+IntToHex(lpCharset^[dwIndex][0], 4)+
                                  IntToHex(lpCharset^[dwIndex][1], 4)+'\'+InfoStr[Info]), lpValue, dwLength) then
                 begin
                    // Set result string
                    SetString(result, PChar(lpValue), dwLength);
                    // Done processing
                    break;
                 end;
              end;
           end;
        end;
     finally
        // Free allocated memory
        FreeMem(lpszBuffer);
     end;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin

  // CompanyName
  ShowMessage(GetFileInfoString('c:\windows\system32\calc.exe', 1));
  // FileDescription
  ShowMessage(GetFileInfoString('c:\windows\system32\calc.exe', 2));
  // FileVersion
  ShowMessage(GetFileInfoString('c:\windows\system32\calc.exe', 3));
  // InternalName
  ShowMessage(GetFileInfoString('c:\windows\system32\calc.exe', 4));

end;

end.

0
 
LVL 16

Author Comment

by:CodedK
ID: 17090594
Thanks Russell :)
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17090625
No problem

Russell
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question