Board index » delphi » VersionInfo - why doesn't this code work!?

VersionInfo - why doesn't this code work!?

I have been playing round with the following function for several days
now and I cannot get it to work.  I have tried several versions of what
is essentially the same code - casting PChars to pointers, using strings
instead of PChars, building up passed values into temporary variables so
I can check the values etc.  None of them work, they all get to the
VerQueryValue and the call does not succeed.  If I look at the contents
of pVersionInfo it seems to contain rubbish.  Anyone shed some light on
the subject?  I am using D4 on NT4 SP4.  I expect to return a string
containing the version number etc. if I call something like

label1.caption := strVersionInfo(3);

But it doesn't work!  I get a different access error on my computer at
home compared to my one at work, but both run the same configuration!,
oh, and yes, the exe DOES contain version info.

function strVersionInfo(iStringNo: Integer): String;
const
  iINFO_NUM = 10;
  strInfo : array [0..iINFO_NUM] of String =
    ('FileVersionInfoSize', 'CompanyName', 'FileDescription',
'FileVersion',
     'InternalName', 'LegalCopyright', 'LegalTradeMarks',
'OriginalFilename',
     'ProductName', 'ProductVersion', 'Comments');
var
  dwInfoSize: DWord;
  dw: DWord;
  dwLen: DWord;
  pVersionInfo: Pointer;
  p2: Pointer;

begin
  Result := '';
  dwInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), dw);
  //this is around 900 odd bytes long
  if dwInfoSize > 0 then
  begin
    if iStringNo = 0 then
      //return the size of the info
      Result := IntToStr(dwInfoSize)//this is the only bit that works!
    else
    begin
      GetMem(pVersionInfo, dwInfoSize);
      try
        if GetFileVersionInfo(PChar(ParamStr(0)), 0, dwInfoSize,
pVersionInfo) then
        begin
          if VerQueryValue(pVersionInfo,
PChar('\StringFileInfo\040904E4\'+ strInfo[iStringNo]), p2, dwLen) then
            Result := String(p2)
          else
            //I always end up on this line :-(
            Result := 'Version access error code:'
+IntToStr(GetLastError);
        end;
      finally
        FreeMem(pVersionInfo);
      end;
    end;
  end;
end;

Trevor

Sent via Deja.com http://www.deja.com/
Before you buy.

 

Re:VersionInfo - why doesn't this code work!?


Quote
In article <7vqe0l$j5...@nnrp1.deja.com>, th...@my-deja.com writes:
>          if VerQueryValue(pVersionInfo,
>PChar('\StringFileInfo\040904E4\'+ strInfo[iStringNo]), p2, dwLen) then

Have you got the correct lang-charset value (you've used 040904e4) ?

Alan Lloyd
alangll...@aol.com

Re:VersionInfo - why doesn't this code work!?


In article <19991104071845.14767.00001...@ngol02.aol.com>,
  alangll...@aol.com (AlanGLLoyd) wrote:
Quote
> In article <7vqe0l$j5...@nnrp1.deja.com>, th...@my-deja.com writes:

> >          if VerQueryValue(pVersionInfo,
> >PChar('\StringFileInfo\040904E4\'+ strInfo[iStringNo]), p2, dwLen)
then

> Have you got the correct lang-charset value (you've used 040904e4) ?

> Alan Lloyd
> alangll...@aol.com

The "magic number" is the same in all the books that I have looked at so
far - Mastering Delphi 3&4, Delphi Help file, Delphi manuals and a
couple of postings I have tried off the net.  Where do I find out which
one to use?  Most of the examples are probably written in the US while I
live in Australia.  Does this mean I use a different lang-charset? If
so, how do I find out which one?

trevor

Sent via Deja.com http://www.deja.com/
Before you buy.

Re:VersionInfo - why doesn't this code work!?


In article <7vstc8$cv...@nnrp1.deja.com>,

Quote
  th...@my-deja.com wrote:
> In article <19991104071845.14767.00001...@ngol02.aol.com>,
>   alangll...@aol.com (AlanGLLoyd) wrote:
> > In article <7vqe0l$j5...@nnrp1.deja.com>, th...@my-deja.com writes:

> > >          if VerQueryValue(pVersionInfo,
> > >PChar('\StringFileInfo\040904E4\'+ strInfo[iStringNo]), p2, dwLen)
> then

> > Have you got the correct lang-charset value (you've used 040904e4) ?

> > Alan Lloyd
> > alangll...@aol.com

> The "magic number" is the same in all the books that I have looked at
so
> far - Mastering Delphi 3&4, Delphi Help file, Delphi manuals and a
> couple of postings I have tried off the net.  Where do I find out
which
> one to use?  Most of the examples are probably written in the US while
I
> live in Australia.  Does this mean I use a different lang-charset? If
> so, how do I find out which one?

> trevor

> Sent via Deja.com http://www.deja.com/
> Before you buy.

Just a bit more information which everyone may like to take note of.  I
received a note in my deja email box concerning the "magic number".
After loading the offending exe file into a hex editor and going to the
end of the file I found the embedded version information.  I noticed
however, my magic number is 0c0904e4 and NOT 040904e4 :-(  I have
subsequently changed my code to use the appropriate code and it no
longer produces an error YEAHHHH!!!! :-)  However, it still doesn't
work, major bummer BOOOOHHH!!! :-(  Hopefully I can get a chance to have
a further look tonight when I get home.  I will investigate the magic
number further.  I guess the problem is that not all the world lives in
the US, which appears to use 04

Trevor

Sent via Deja.com http://www.deja.com/
Before you buy.

Re:VersionInfo - why doesn't this code work!?


th...@my-deja.com skrev i meldingen <7vstc8$cv...@nnrp1.deja.com>...

Quote
>In article <19991104071845.14767.00001...@ngol02.aol.com>,
>AlanGLLoyd wrote:
>> >          if VerQueryValue(pVersionInfo,
>> >PChar('\StringFileInfo\040904E4\'+ strInfo[iStringNo]), p2, dwLen)
>then

>> Have you got the correct lang-charset value (you've used 040904e4)
?

>The "magic number" is the same in all the books that I have looked at
so
>far - Mastering Delphi 3&4, Delphi Help file, Delphi manuals and a
>couple of postings I have tried off the net.  Where do I find out
which
>one to use?  Most of the examples are probably written in the US
while I
>live in Australia.  Does this mean I use a different lang-charset? If
>so, how do I find out which one?

The "internationalized" way to do this is querying the LANGID value.
Here's a method code to incorporate this call (don't feel bad if it
seems odd, I remember using quite some time to get the LANGID value
right, one of the "odder" APIs...):

<snip>
procedure TApp.GetExeFileInfo;
var
  InfoSize   : DWord;
  DummyH     : DWord;
  Buffer,
  ResBuffer  : Pointer;
  ResLen     : DWord;
  LangId     : DWord;
begin
  InfoSize:=0;
  InfoSize:=GetFileVersionInfoSize(PChar(Application.exename),
DummyH);
  if InfoSize > 0 then begin
    Buffer:=AllocMem(InfoSize);
    try
      GetFileVersionInfo(PChar(Application.exename), 0, Infosize,
Buffer);
      ResBuffer:=nil;
      ResLen:=0;
      VerQueryValue(Buffer, PChar('\VarFileInfo\Translation'),
ResBuffer, ResLen);
      LangId:=DWord(ResBuffer^);
      SwapWords(LangId);
      VerQueryValue(Buffer, PChar('\StringFileInfo\'+IntToHex(LangId,
8)+'\ProductVersion'), ResBuffer, ResLen);
      if ResLen > 0 then
        FVersion:=PChar(ResBuffer);
      VerQueryValue(Buffer, PChar('\StringFileInfo\'+IntToHex(LangId,
8)+'\FileVersion'), ResBuffer, ResLen);
      if ResLen > 0 then
        FVersionBuild:=PChar(ResBuffer);
      VerQueryValue(Buffer, PChar('\StringFileInfo\'+IntToHex(LangId,
8)+'\BuildType'), ResBuffer, ResLen);
      if ResLen > 0 then
        FReleaseType:=PChar(ResBuffer)[0];
      VerQueryValue(Buffer, PChar('\StringFileInfo\'+IntToHex(LangId,
8)+'\ProductName'), ResBuffer, ResLen);
      if ResLen > 0 then begin
        FAppTitle:=PChar(ResBuffer);
        Application.Title:=FAppTitle;
      end;
    finally
      FreeMem(Buffer, InfoSize);
    end;
  end;
end;
</snip>

Good luck !
--

Bjoerge

Re:VersionInfo - why doesn't this code work!?


Quote
In article <7vt3cl$hg...@nnrp1.deja.com>, th...@my-deja.com writes:
> I noticed
>however, my magic number is 0c0904e4 and NOT 040904e4 :-(  I have
>subsequently changed my code to use the appropriate code and it no
>longer produces an error YEAHHHH!!!! :-)  However, it still doesn't
>work, major bummer BOOOOHHH!!! :-(  Hopefully I can get a chance to have
>a further look tonight when I get home.  I will investigate the magic
>number further.  I guess the problem is that not all the world lives in
>the US, which appears to use 04

I just tried the code below and if I set my computer regional settings to
English(Australian) pLang returns 0c09, US 0409, UK 0809.

procedure TForm1.FormActivate(Sender: TObject);
 var
  plang: string;
  psLang: array[0..4] of char;
begin

GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,LOCALE_IDEFAULTLANGUAGE,@psLang,SizeOf
(psLang));
plang:= psLang;

end;

Gordon Whittam.
~~~~~~~~~~~~~~~~~~~~~~~~
Certifiable - definitely <g>

http://members.aol.com/mgcsoft/  (the function junction equation editor)
http://members.aol.com/delphistuf/delphstf.htm   (Delphi bits and bobs and a
few links)

MGCSoft

Re:VersionInfo - why doesn't this code work!?


   I am using D3 and Win95.
String(p2) is an 'Invalid typecast'.  It does not trigger an immediate
error, but try it in the 'Evaluate/Modify...' window.  Typecast the pointer
as a PChar then assign the result to the string.

            Result := PChar(p2)   // String(p2)

--
                                                                     Cleon,

http://www.ionet.net/~baileyct

Luck is a lifetime of practice, followed by a moment of opportunity.
People decide what they believe, then look for reasons to believe it.

Quote
th...@my-deja.com wrote in message <7vqe0l$j5...@nnrp1.deja.com>...
>I have been playing round with the following function for several days
>now and I cannot get it to work.  I have tried several versions of what
>is essentially the same code - casting PChars to pointers, using strings
>instead of PChars, building up passed values into temporary variables so
>I can check the values etc.  None of them work, they all get to the
>VerQueryValue and the call does not succeed.  If I look at the contents
>of pVersionInfo it seems to contain rubbish.  Anyone shed some light on
>the subject?  I am using D4 on NT4 SP4.  I expect to return a string
>containing the version number etc. if I call something like

>label1.caption := strVersionInfo(3);

>But it doesn't work!  I get a different access error on my computer at
>home compared to my one at work, but both run the same configuration!,
>oh, and yes, the exe DOES contain version info.

>function strVersionInfo(iStringNo: Integer): String;
>const
>  iINFO_NUM = 10;
>  strInfo : array [0..iINFO_NUM] of String =
>    ('FileVersionInfoSize', 'CompanyName', 'FileDescription',
>'FileVersion',
>     'InternalName', 'LegalCopyright', 'LegalTradeMarks',
>'OriginalFilename',
>     'ProductName', 'ProductVersion', 'Comments');
>var
>  dwInfoSize: DWord;
>  dw: DWord;
>  dwLen: DWord;
>  pVersionInfo: Pointer;
>  p2: Pointer;

>begin
>  Result := '';
>  dwInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), dw);
>  //this is around 900 odd bytes long
>  if dwInfoSize > 0 then
>  begin
>    if iStringNo = 0 then
>      //return the size of the info
>      Result := IntToStr(dwInfoSize)//this is the only bit that works!
>    else
>    begin
>      GetMem(pVersionInfo, dwInfoSize);
>      try
>        if GetFileVersionInfo(PChar(ParamStr(0)), 0, dwInfoSize,
>pVersionInfo) then
>        begin
>          if VerQueryValue(pVersionInfo,
>PChar('\StringFileInfo\040904E4\'+ strInfo[iStringNo]), p2, dwLen) then
>            Result := String(p2)
>          else
>            //I always end up on this line :-(
>            Result := 'Version access error code:'
>+IntToStr(GetLastError);
>        end;
>      finally
>        FreeMem(pVersionInfo);
>      end;
>    end;
>  end;
>end;

>Trevor

>Sent via Deja.com http://www.deja.com/
>Before you buy.

Re:VersionInfo - why doesn't this code work!?


Quote
<th...@my-deja.com> wrote in message news:7vqe0l$j5g$1@nnrp1.deja.com...
> I have been playing round with the following function for several days
> now and I cannot get it to work.  I have tried several versions of what

<snip>
> Trevor

> Sent via Deja.com http://www.deja.com/
> Before you buy.

I get the same problem when I do this.  By checking, I find that it is
VerQueryValue returning false.  This indicates it can't find the string in
question.  Which is strange, as I have confirmed it is there. Windows and
everything else can read it.

It's not a problem of the resource not loading completely, it can read the
translation table, which is AFTER the string table (and at the end of the
resource).
It's not the lang-charset, because I know what it is (I get it from the
translation table anyway).

I can get VerQueryValue to return true on '\StringFileInfo\100904E4' (my
lang is English (canadian)), but when I add '\CompanyName' or any of the
other strings, VerQueryValue Fails.

--
John D. Yarrow
john_yar...@mail.com
http://user.fundy.net/jdyarrow

Re:VersionInfo - why doesn't this code work!?


In article <807qcb$n8...@bignews.fundy.net>,
  "John D. Yarrow" <john_yar...@NOSPAM.mail.com> wrote:
Quote

> <th...@my-deja.com> wrote in message

news:7vqe0l$j5g$1@nnrp1.deja.com...
Quote
> > I have been playing round with the following function for several
days
> > now and I cannot get it to work.  I have tried several versions of
what

> <snip>
> > Trevor

> > Sent via Deja.com http://www.deja.com/
> > Before you buy.

> I get the same problem when I do this.  By checking, I find that it is
> VerQueryValue returning false.  This indicates it can't find the
string in
> question.  Which is strange, as I have confirmed it is there. Windows
and
> everything else can read it.

> It's not a problem of the resource not loading completely, it can read
the
> translation table, which is AFTER the string table (and at the end of
the
> resource).
> It's not the lang-charset, because I know what it is (I get it from
the
> translation table anyway).

> I can get VerQueryValue to return true on '\StringFileInfo\100904E4'
(my
> lang is English (canadian)), but when I add '\CompanyName' or any of
the
> other strings, VerQueryValue Fails.

> --
> John D. Yarrow
> john_yar...@mail.com
> http://user.fundy.net/jdyarrow

After reading several replies to my original posting I now have my code
working.  The main problem was an invalid cast of the returned pointer
value to a string - String(p2) does not work while String(PChar(p2))
does!  The other problem was getting the Language ID correct, the value
can be read from the project settings box, however this does not make
for a generic solution as my code would not extract information from an
exe compiled in the US for example.  Someone else posted the following
line of code which allows me to extract the ID which I can then use to
get what I need.  I guess this is what you are using.

GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,LOCALE_IDEFAULTLANGUAGE,@psLang,Size
Of (psLang));

In reply to your problem however, if I select other strings such as
CompanyName, I don't have a problem.  So I don't know why yours doesn't
work!  Maybe also an invalid cast?  Are you placing the return value
into a pointer?

The version info calls are not the best written ones in my opinion :-)

Trevor

Sent via Deja.com http://www.deja.com/
Before you buy.

Other Threads