For Programmers: Free Programming Magazines  


Home > Archive > Visual Basic Syntax > February 2005 > VerQueryValue









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author VerQueryValue
Danny

2005-01-26, 8:59 pm

In the code below I'm trying to get File Version number and everything
works except the very last step: VerQueryValue (bRetCode returns
False, and both output variables are 0).

I examined the string returned by GetFileVersionInfo and it looks
fine; FileVersion exists (see dump below).

The only oddity is that the API Viewer had a small error in the
Declare; the Alias did not have an "A" at the end which I added.

Thanks!

--- declare ---

Public Declare Function VerQueryValue Lib "version.dll" _
Alias "VerQueryValueA" ( _
pBlock As Any, _
ByVal lpSubBlock As String, _
ByVal lplpBuffer As Long, _
puLen As Long) _
As Long

--- code ---

Public Sub GetMAIDVersion()
Dim i As Long

Dim dwVerInfoSize As Long
Dim lpVersion As Long
Dim dwVerHnd As Long
Dim puVersionLen As Long
Dim bRetCode As Boolean

Dim szFileName As String
szFileName = App.Path & MAIDname

dwVerHnd = 0

dwVerInfoSize = GetFileVersionInfoSize(szFileName, dwVerHnd)

If dwVerInfoSize > 0 Then
Dim lpstrVffInfo() As Byte
ReDim lpstrVffInfo(dwVerInfoSize)

i = GetFileVersionInfo( _
szFileName, _
dwVerHnd, _
dwVerInfoSize, _
lpstrVffInfo(0))

Dim FileVersion As String
FileVersion = "\\StringFileInfo\\040904E4\\FileVersion" & Chr(0)

' get file version
bRetCode = VerQueryValue( _
lpstrVffInfo(0), _
"\\StringFileInfo\\040904E4\\FileVersion", _
lpVersion, _
puVersionLen)
Stop

End If
End Sub

--- FileVersionInfo dump ---

00000000: E0 01 34 00 56 53 5F 56 45 52 53 49 4F 4E 5F 49
"..4.VS_VERSION_I"
00000010: 4E 46 4F 00 BD 04 EF FE 00 00 01 00 00 00 01 00
"NFO............."
00000020: C2 0B 00 00 00 00 04 00 00 00 00 00 3F 00 00 00
"............?..."
00000030: 00 00 00 00 04 00 04 00 02 00 00 00 00 00 00 00
"................"
00000040: 00 00 00 00 00 00 00 00 74 01 00 00 53 74 72 69
"........t...Stri"
00000050: 6E 67 46 69 6C 65 49 6E 66 6F 00 00 60 01 00 00
"ngFileInfo..`..."
00000060: 30 34 30 39 30 31 42 35 00 00 6E 00 24 00 12 00
"040901B5..n.$..."
00000070: 43 6F 6D 6D 65 6E 74 73 00 00 66 00 4E 69 6B 6F
"Comments..f.Niko"
00000080: 6E 20 53 63 61 6E 20 44 72 69 76 65 72 00 30 00 "n Scan
Driver.0."
00000090: 24 00 12 00 43 6F 6D 70 61 6E 79 4E 61 6D 65 00
"$...CompanyName."
000000A0: 4E 69 6B 6F 6E 20 43 6F 72 70 6F 72 61 74 69 6F "Nikon
Corporatio"
000000B0: 6E 00 69 00 28 00 12 00 46 69 6C 65 44 65 73 63
"n.i.(...FileDesc"
000000C0: 72 69 70 74 69 6F 6E 00 4E 69 6B 6F 6E 20 53 63
"ription.Nikon Sc"
000000D0: 61 6E 20 44 72 69 76 65 72 00 43 00 20 00 0E 00 "an
Driver.C. ..."
000000E0: 46 69 6C 65 56 65 72 73 69 6F 6E 00 31 2C 20 30
"FileVersion.1, 0"
000000F0: 2C 20 30 2C 20 33 30 31 30 00 6F 00 1C 00 07 00 ", 0,
3010.o....."
00000100: 49 6E 74 65 72 6E 61 6C 4E 61 6D 65 00 00 74 00
"InternalName..t."
00000110: 4C 53 35 30 30 30 00 00 44 00 2D 00 4C 65 67 61
"LS5000..D.-.Lega"
00000120: 6C 43 6F 70 79 72 69 67 68 74 00 00 43 6F 70 79
"lCopyright..Copy"
00000130: 72 69 67 68 74 20 28 43 29 20 4E 69 6B 6F 6E 20 "right
(C) Nikon "
00000140: 43 6F 72 70 6F 72 61 74 69 6F 6E 2E 20 31 39 39
"Corporation. 199"
00000150: 35 20 2D 20 32 30 30 33 00 00 69 00 24 00 0B 00 "5 -
2003..i.$..."
00000160: 4F 72 69 67 69 6E 61 6C 46 69 6C 65 6E 61 6D 65
"OriginalFilename"
00000170: 00 00 56 00 4C 53 35 30 30 30 2E 4D 44 33 00 00
"..V.LS5000.MD3.."
00000180: 1C 00 0B 00 50 72 6F 64 75 63 74 4E 61 6D 65 00
"....ProductName."
00000190: 4E 69 6B 6F 6E 20 53 63 61 6E 00 00 20 00 0B 00 "Nikon
Scan.. ..."
000001A0: 50 72 6F 64 75 63 74 56 65 72 73 69 6F 6E 00 00
"ProductVersion.."
000001B0: 34 2C 20 30 2C 20 30 2C 20 30 00 00 24 00 00 00 "4, 0,
0, 0..$..."
000001C0: 56 61 72 46 69 6C 65 49 6E 66 6F 00 14 00 04 00
"VarFileInfo....."
000001D0: 54 72 61 6E 73 6C 61 74 69 6F 6E 00 09 04 B5 01
"Translation....."
000001E0: 43 00 6F 00 70 00 79 00 72 00 69 00 67 00 68 00
"C.o.p.y.r.i.g.h."
000001F0: 74 00 00 00 43 00 6F 00 70 00 79 00 72 00 69 00
"t...C.o.p.y.r.i."
00000200: 67 00 68 00 74 00 20 00 28 00 43 00 29 00 20 00 "g.h.t.
..(.C.). ."
00000210: 4E 00 69 00 6B 00 6F 00 6E 00 20 00 43 00 6F 00
"N.i.k.o.n. .C.o."
00000220: 72 00 70 00 6F 00 72 00 61 00 74 00 69 00 6F 00
"r.p.o.r.a.t.i.o."
00000230: 6E 00 2E 00 20 00 31 00 39 00 39 00 35 00 20 00 "n...
1.9.9.5. ."
00000240: 2D 00 20 00 32 00 30 00 30 00 33 00 00 00 00 00 "-.
2.0.0.3....."
00000250: 3E 00 0B 00 01 00 4F 00 72 00 69 00 67 00 69 00
">.....O.r.i.g.i."
00000260: 6E 00 61 00 6C 00 46 00 69 00 6C 00 65 00 6E 00
"n.a.l.F.i.l.e.n."
00000270: 61 00 6D 00 65 00 00 00 4C 00 53 00 35 00 30 00
"a.m.e...L.S.5.0."
00000280: 30 00 30 00 2E 00 4D 00 44 00 33 00 00 00 00 00
"0.0...M.D.3....."
00000290: 36 00 0B 00 01 00 50 00 72 00 6F 00 64 00 75 00
"6.....P.r.o.d.u."
000002A0: 63 00 74 00 4E 00 61 00 6D 00 65 00 00 00 00 00
"c.t.N.a.m.e....."
000002B0: 4E 00 69 00 6B 00 6F 00 6E 00 20 00 53 00 63 00
"N.i.k.o.n. .S.c."
000002C0: 61 00 6E 00 00 00 00 00 3A 00 0B 00 01 00 50 00
"a.n.....:.....P."
000002D0: 72 00 6F 00 64 00 75 00 63 00 74 00 56 00 65 00
"r.o.d.u.c.t.V.e."
000002E0: 72 00 73 00 69 00 6F 00 6E 00 00 00 34 00 2C 00
"r.s.i.o.n...4.,."
000002F0: 20 00 30 00 2C 00 20 00 30 00 2C 00 20 00 30 00 " .0.,.
..0.,. .0."
00000300: 00 00 00 00 44 00 00 00 01 00 56 00 61 00 72 00
"....D.....V.a.r."
00000310: 46 00 69 00 6C 00 65 00 49 00 6E 00 66 00 6F 00
"F.i.l.e.I.n.f.o."
00000320: 00 00 00 00 24 00 04 00 00 00 54 00 72 00 61 00
"....$.....T.r.a."
00000330: 6E 00 73 00 6C 00 61 00 74 00 69 00 6F 00 6E 00
"n.s.l.a.t.i.o.n."
00000340: 00 00 00 00 09 04 B5 01
"........"

--- end ---

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Karl E. Peterson

2005-01-26, 8:59 pm

I don't see the problem immediately, but you might want to compare your code to that
at http://vb.mvps.org/samples/FileInfo (which does work with this call).
--
[Microsoft Basic: 1976-2001, RIP]


Danny wrote:
> In the code below I'm trying to get File Version number and everything
> works except the very last step: VerQueryValue (bRetCode returns
> False, and both output variables are 0).
>
> I examined the string returned by GetFileVersionInfo and it looks
> fine; FileVersion exists (see dump below).
>
> The only oddity is that the API Viewer had a small error in the
> Declare; the Alias did not have an "A" at the end which I added.
>
> Thanks!
>
> --- declare ---
>
> Public Declare Function VerQueryValue Lib "version.dll" _
> Alias "VerQueryValueA" ( _
> pBlock As Any, _
> ByVal lpSubBlock As String, _
> ByVal lplpBuffer As Long, _
> puLen As Long) _
> As Long
>
> --- code ---
>
> Public Sub GetMAIDVersion()
> Dim i As Long
>
> Dim dwVerInfoSize As Long
> Dim lpVersion As Long
> Dim dwVerHnd As Long
> Dim puVersionLen As Long
> Dim bRetCode As Boolean
>
> Dim szFileName As String
> szFileName = App.Path & MAIDname
>
> dwVerHnd = 0
>
> dwVerInfoSize = GetFileVersionInfoSize(szFileName, dwVerHnd)
>
> If dwVerInfoSize > 0 Then
> Dim lpstrVffInfo() As Byte
> ReDim lpstrVffInfo(dwVerInfoSize)
>
> i = GetFileVersionInfo( _
> szFileName, _
> dwVerHnd, _
> dwVerInfoSize, _
> lpstrVffInfo(0))
>
> Dim FileVersion As String
> FileVersion = "\\StringFileInfo\\040904E4\\FileVersion" & Chr(0)
>
> ' get file version
> bRetCode = VerQueryValue( _
> lpstrVffInfo(0), _
> "\\StringFileInfo\\040904E4\\FileVersion", _
> lpVersion, _
> puVersionLen)
> Stop
>
> End If
> End Sub
>
> --- FileVersionInfo dump ---
>
> 00000000: E0 01 34 00 56 53 5F 56 45 52 53 49 4F 4E 5F 49
> "..4.VS_VERSION_I"
> 00000010: 4E 46 4F 00 BD 04 EF FE 00 00 01 00 00 00 01 00
> "NFO............."
> 00000020: C2 0B 00 00 00 00 04 00 00 00 00 00 3F 00 00 00
> "............?..."
> 00000030: 00 00 00 00 04 00 04 00 02 00 00 00 00 00 00 00
> "................"
> 00000040: 00 00 00 00 00 00 00 00 74 01 00 00 53 74 72 69
> "........t...Stri"
> 00000050: 6E 67 46 69 6C 65 49 6E 66 6F 00 00 60 01 00 00
> "ngFileInfo..`..."
> 00000060: 30 34 30 39 30 31 42 35 00 00 6E 00 24 00 12 00
> "040901B5..n.$..."
> 00000070: 43 6F 6D 6D 65 6E 74 73 00 00 66 00 4E 69 6B 6F
> "Comments..f.Niko"
> 00000080: 6E 20 53 63 61 6E 20 44 72 69 76 65 72 00 30 00 "n Scan
> Driver.0."
> 00000090: 24 00 12 00 43 6F 6D 70 61 6E 79 4E 61 6D 65 00
> "$...CompanyName."
> 000000A0: 4E 69 6B 6F 6E 20 43 6F 72 70 6F 72 61 74 69 6F "Nikon
> Corporatio"
> 000000B0: 6E 00 69 00 28 00 12 00 46 69 6C 65 44 65 73 63
> "n.i.(...FileDesc"
> 000000C0: 72 69 70 74 69 6F 6E 00 4E 69 6B 6F 6E 20 53 63
> "ription.Nikon Sc"
> 000000D0: 61 6E 20 44 72 69 76 65 72 00 43 00 20 00 0E 00 "an
> Driver.C. ..."
> 000000E0: 46 69 6C 65 56 65 72 73 69 6F 6E 00 31 2C 20 30
> "FileVersion.1, 0"
> 000000F0: 2C 20 30 2C 20 33 30 31 30 00 6F 00 1C 00 07 00 ", 0,
> 3010.o....."
> 00000100: 49 6E 74 65 72 6E 61 6C 4E 61 6D 65 00 00 74 00
> "InternalName..t."
> 00000110: 4C 53 35 30 30 30 00 00 44 00 2D 00 4C 65 67 61
> "LS5000..D.-.Lega"
> 00000120: 6C 43 6F 70 79 72 69 67 68 74 00 00 43 6F 70 79
> "lCopyright..Copy"
> 00000130: 72 69 67 68 74 20 28 43 29 20 4E 69 6B 6F 6E 20 "right
> (C) Nikon "
> 00000140: 43 6F 72 70 6F 72 61 74 69 6F 6E 2E 20 31 39 39
> "Corporation. 199"
> 00000150: 35 20 2D 20 32 30 30 33 00 00 69 00 24 00 0B 00 "5 -
> 2003..i.$..."
> 00000160: 4F 72 69 67 69 6E 61 6C 46 69 6C 65 6E 61 6D 65
> "OriginalFilename"
> 00000170: 00 00 56 00 4C 53 35 30 30 30 2E 4D 44 33 00 00
> "..V.LS5000.MD3.."
> 00000180: 1C 00 0B 00 50 72 6F 64 75 63 74 4E 61 6D 65 00
> "....ProductName."
> 00000190: 4E 69 6B 6F 6E 20 53 63 61 6E 00 00 20 00 0B 00 "Nikon
> Scan.. ..."
> 000001A0: 50 72 6F 64 75 63 74 56 65 72 73 69 6F 6E 00 00
> "ProductVersion.."
> 000001B0: 34 2C 20 30 2C 20 30 2C 20 30 00 00 24 00 00 00 "4, 0,
> 0, 0..$..."
> 000001C0: 56 61 72 46 69 6C 65 49 6E 66 6F 00 14 00 04 00
> "VarFileInfo....."
> 000001D0: 54 72 61 6E 73 6C 61 74 69 6F 6E 00 09 04 B5 01
> "Translation....."
> 000001E0: 43 00 6F 00 70 00 79 00 72 00 69 00 67 00 68 00
> "C.o.p.y.r.i.g.h."
> 000001F0: 74 00 00 00 43 00 6F 00 70 00 79 00 72 00 69 00
> "t...C.o.p.y.r.i."
> 00000200: 67 00 68 00 74 00 20 00 28 00 43 00 29 00 20 00 "g.h.t.
> .(.C.). ."
> 00000210: 4E 00 69 00 6B 00 6F 00 6E 00 20 00 43 00 6F 00
> "N.i.k.o.n. .C.o."
> 00000220: 72 00 70 00 6F 00 72 00 61 00 74 00 69 00 6F 00
> "r.p.o.r.a.t.i.o."
> 00000230: 6E 00 2E 00 20 00 31 00 39 00 39 00 35 00 20 00 "n...
> 1.9.9.5. ."
> 00000240: 2D 00 20 00 32 00 30 00 30 00 33 00 00 00 00 00 "-.
> 2.0.0.3....."
> 00000250: 3E 00 0B 00 01 00 4F 00 72 00 69 00 67 00 69 00
> ">.....O.r.i.g.i."
> 00000260: 6E 00 61 00 6C 00 46 00 69 00 6C 00 65 00 6E 00
> "n.a.l.F.i.l.e.n."
> 00000270: 61 00 6D 00 65 00 00 00 4C 00 53 00 35 00 30 00
> "a.m.e...L.S.5.0."
> 00000280: 30 00 30 00 2E 00 4D 00 44 00 33 00 00 00 00 00
> "0.0...M.D.3....."
> 00000290: 36 00 0B 00 01 00 50 00 72 00 6F 00 64 00 75 00
> "6.....P.r.o.d.u."
> 000002A0: 63 00 74 00 4E 00 61 00 6D 00 65 00 00 00 00 00
> "c.t.N.a.m.e....."
> 000002B0: 4E 00 69 00 6B 00 6F 00 6E 00 20 00 53 00 63 00
> "N.i.k.o.n. .S.c."
> 000002C0: 61 00 6E 00 00 00 00 00 3A 00 0B 00 01 00 50 00
> "a.n.....:.....P."
> 000002D0: 72 00 6F 00 64 00 75 00 63 00 74 00 56 00 65 00
> "r.o.d.u.c.t.V.e."
> 000002E0: 72 00 73 00 69 00 6F 00 6E 00 00 00 34 00 2C 00
> "r.s.i.o.n...4.,."
> 000002F0: 20 00 30 00 2C 00 20 00 30 00 2C 00 20 00 30 00 " .0.,.
> .0.,. .0."
> 00000300: 00 00 00 00 44 00 00 00 01 00 56 00 61 00 72 00
> "....D.....V.a.r."
> 00000310: 46 00 69 00 6C 00 65 00 49 00 6E 00 66 00 6F 00
> "F.i.l.e.I.n.f.o."
> 00000320: 00 00 00 00 24 00 04 00 00 00 54 00 72 00 61 00
> "....$.....T.r.a."
> 00000330: 6E 00 73 00 6C 00 61 00 74 00 69 00 6F 00 6E 00
> "n.s.l.a.t.i.o.n."
> 00000340: 00 00 00 00 09 04 B5 01
> "........"
>
> --- end ---
>
> Danny
>
> (You guessed it! ;o) Remove NOSPAMFOR before emailing.)




Danny

2005-01-26, 8:59 pm

Thanks, Karl, I'll have a look.

In the meantime, I forgot to mention last time:

VB6 under W98.


Date: Wed, 26 Jan 2005 13:50:48 -0800
Name: "Karl E. Peterson" <karl@mvps.org>

>I don't see the problem immediately, but you might want to compare your code to that
>at http://vb.mvps.org/samples/FileInfo (which does work with this call).
>--
>[Microsoft Basic: 1976-2001, RIP]
>
>
>Danny wrote:
>
>
>



Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Sam Hobbs

2005-01-26, 8:59 pm

Comments are inline.

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41f80bfb.11448067@News.Individual.NET...
>
> If dwVerInfoSize > 0 Then
> Dim lpstrVffInfo() As Byte
> ReDim lpstrVffInfo(dwVerInfoSize)


I think you are allocating an extra byte, but that is probably not a problem
here.

> Dim FileVersion As String
> FileVersion = "\\StringFileInfo\\040904E4\\FileVersion" & Chr(0)


Concatenating Chr(0) is probably not necessary but probably is not a problem
here. However this won't work in VB because of the "\\"; you need only one
"\". The double backslashes ("\\") are needed only for C/C++.

> bRetCode = VerQueryValue( _
> lpstrVffInfo(0), _
> "\\StringFileInfo\\040904E4\\FileVersion", _
> lpVersion, _
> puVersionLen)



First, a trivial comment is that you can use FileVersion as the second
parameter; you have it bu you are not using it.

Converting SDK code to VB syntax is probably more work than you realize.

One thing that you need to do is to ensure you are using the correct
language and code page identifier. You probably are not. If you are not
familiar with that, then you need to learn more about resources.

You need to check the value of bRetCode to ensure that VerQueryValue worked.
In fact, you should check the return code of all SDK functions that return a
value that indicates success or failure. bRetCode is probably zero,
indicating failure, in which situation you must assume that the output of
VerQueryValue is not valid.

Finally, the third parameter of VerQueryValue is a pointer to a
(non-Unicode) string. That seems to be something that could easily be a
problem for VB. You must ensure you do that correctly, which would be very
different from what is usually done, even in calls to Windows SDK functions.

I did not notice until I was nearly done with this that you have
cross-posted. I often ignore messages that are cross-posted, mainly because
people nearly always are too liberal about the newsgroups that they
cross-post to. In other words, people often cross-post to newsgroups that
the question is innapropriate for. I am sure that you are going to say that
you need to, and I sure don't need to spend so much time answering a
question.


Danny

2005-01-27, 3:58 am

Found it!

ByVal lplpBuffer As Long, _

should be:

lplpBuffer As Any, _

Which means API Viewer not only had the Alias wrong but the whole
definition was messed up.


Date: Wed, 26 Jan 2005 13:50:48 -0800
Name: "Karl E. Peterson" <karl@mvps.org>

>I don't see the problem immediately, but you might want to compare your code to that
>at http://vb.mvps.org/samples/FileInfo (which does work with this call).
>--
>[Microsoft Basic: 1976-2001, RIP]
>
>
>Danny wrote:
>
>
>



Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Danny

2005-01-27, 3:58 am

Date: Wed, 26 Jan 2005 16:31:28 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>
>I think you are allocating an extra byte, but that is probably not a problem
>here.


I did try (0 to (dwVerInfoSize - 1)) but it didn't make any
difference.

The problem was elsewhere. The API Viewer definition was all wrong. In
addition to the missing Alias:
ByVal lplpBuffer As Long, _
should have been:
lplpBuffer As Any, _

>
>Concatenating Chr(0) is probably not necessary but probably is not a problem
>here. However this won't work in VB because of the "\\"; you need only one
>"\". The double backslashes ("\\") are needed only for C/C++.


Even with corrected definition and single backslashes, trying to get
FileVersion specifically still doesn't work. In the end, I simply used
"\" to get all information. That works and I just parse what I need.

& Chr(0) was another desperate attempt even though I know that VB
strings are already 0-terminated.

>
>
>First, a trivial comment is that you can use FileVersion as the second
>parameter; you have it bu you are not using it.


I did, but it didn't make any difference - so I tried a literal.

You see, I've been massaging this code for a while so that's why
there's a lot of chaff all over the place. This is by no means
production code.

>Converting SDK code to VB syntax is probably more work than you realize.


Oh, I know that very well! ;o)

But that's nothing compared to converting C code using a C-style DLL
into VB! One small realloc in the DLL and all your neat VB structures
are dereferenced... Fun!

>One thing that you need to do is to ensure you are using the correct
>language and code page identifier. You probably are not.


Yup, tried that too! It only managed to crash VB spectacularly.

I was on the verge of disassembling the API call to see what's really
going on.

>You need to check the value of bRetCode to ensure that VerQueryValue worked.


As I mention in the original post, I did and it always returned False.

>I did not notice until I was nearly done with this that you have
>cross-posted.


If I hadn't (and multi-posted instead) the MVPs would get really,
really upset. Apparently, that's a very touchy subject in here...

>I often ignore messages that are cross-posted, mainly because
>people nearly always are too liberal about the newsgroups that they
>cross-post to.


The three groups I crossposted to were all relevant. In the end it was
a "syntax" error in a "winapi" caused by a "general" fault in the API
Viewer. Can't get any more relevant! ;o)

Thanks for the reply!

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Sam Hobbs

2005-01-27, 3:58 am

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41f8631a.2498698@News.Individual.NET...
> Found it!
>
> ByVal lplpBuffer As Long, _
>
> should be:
>
> lplpBuffer As Any, _
>
> Which means API Viewer not only had the Alias wrong but the whole
> definition was messed up.


It depends on how you call VerQueryValue. The following works for me.


Private Declare Function GetFileVersionInfo Lib "version.dll" Alias
"GetFileVersionInfoA" _
(ByVal lptstrFilename As String, ByVal dwHandle As Long, ByVal dwLen
As Long, lpData As Any) As Long
Private Declare Function GetFileVersionInfoSize Lib "version.dll" Alias
"GetFileVersionInfoSizeA" _
(ByVal lptstrFilename As String, lpdwHandle As Long) As Long
Private Declare Function VerQueryValue Lib "version.dll" Alias
"VerQueryValueA" _
(pBlock As Any, ByVal lpSubBlock As String, ByVal lplpBuffer As
Long, puLen As Long) As Long

Private Sub Form_Load()
Dim dwVerInfoSize As Long
Dim lpVersion As Long
Dim dwVerHnd As Long
Dim puVersionLen As Long
Dim szFileName As String
Dim FileVersion As String
Dim ResourceBlock() As Byte
Dim VersionInfoBytes() As Byte
Dim VersionInfo As String
Dim RetCode As Long
szFileName = App.Path & "\" & App.EXEName & ".exe"
dwVerInfoSize = GetFileVersionInfoSize(szFileName, dwVerHnd)
If dwVerInfoSize <= 0 Then
Exit Sub
End If
ReDim ResourceBlock(dwVerInfoSize)
RetCode = GetFileVersionInfo(szFileName, dwVerHnd, _
dwVerInfoSize, ResourceBlock(0))
FileVersion = "\StringFileInfo\040904B0\FileVersion"
RetCode = VerQueryValue(ResourceBlock(0), FileVersion, VarPtr(lpVersion),
puVersionLen)
If RetCode = 0 Then
Text1 = "No FileVersion"
Exit Sub
End If
ReDim VersionInfoBytes(puVersionLen - 1)
CopyMemory VersionInfoBytes(0), ByVal lpVersion, puVersionLen
Text1 = StrConv(VersionInfoBytes, vbUnicode)
End Sub


Sam Hobbs

2005-01-27, 3:58 am

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41f87099.5953866@News.Individual.NET...
>
> The problem was elsewhere. The API Viewer definition was all wrong. In
> addition to the missing Alias:
> ByVal lplpBuffer As Long, _
> should have been:
> lplpBuffer As Any, _


See my other reply.

> You see, I've been massaging this code for a while so that's why
> there's a lot of chaff all over the place. This is by no means
> production code.


I understand the frustration very much. For beginners learning C/C++,
pointers are understandably difficult to get accustomed to. I can work with
C/C++ pointers very well well, but I get frustrated with ByRef, ByVal, and
the other memory-access operators and functions. VB was not designed to do
the low-level stuff so it is not well designed in VB. Microsoft defines VB
as being easy to use, but stuff that are not designed to be done easily in
VB can be more difficult than for C/C++.

> As I mention in the original post, I did and it always returned False.


Which means it did not work and it is foolish to go any further.

> The three groups I crossposted to were all relevant. In the end it was
> a "syntax" error in a "winapi" caused by a "general" fault in the API
> Viewer. Can't get any more relevant! ;o)


I think it was not a VB syntax error. I think it was entirely a winapi
question. I think my sample in my other reply shows that.


Danny

2005-01-27, 4:04 pm

Date: Wed, 26 Jan 2005 22:05:19 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>
>I understand the frustration very much. For beginners learning C/C++,
>pointers are understandably difficult to get accustomed to. I can work with
>C/C++ pointers very well well, but I get frustrated with ByRef, ByVal, and
>the other memory-access operators and functions.


You and me both! I also don't find pointers a problem as such. The
problem is VB's limited support of pointers. This is not a criticism,
however, because...

>VB was not designed to do
>the low-level stuff so it is not well designed in VB. Microsoft defines VB
>as being easy to use, but stuff that are not designed to be done easily in
>VB can be more difficult than for C/C++.


Exactly! VB has been intentionally designed to, among other things,
spare the programmer worrying about pointers (we used to call such
languages 4GL).

Strictly speaking, employing APIs in VB is really a "misuse" of the
language.

>
>Which means it did not work and it is foolish to go any further.


Well, according to that I should've given up at the first sign of
trouble. Instead, I tried various approaches and only when I was at
the end of my tether I asked for second opinion.

>
>I think it was not a VB syntax error. I think it was entirely a winapi
>question. I think my sample in my other reply shows that.


The MVPs stormtroopers ;o) patrolling these groups are very vigilant
when it comes to (what they consider) inappropriate cross and
multi-posting. So, either they're slacking off or they found my
crosspost acceptable.

But I do take your point.

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Danny

2005-01-27, 4:04 pm

Date: Wed, 26 Jan 2005 21:35:58 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>
>It depends on how you call VerQueryValue. The following works for me.


.... code omitted for brevity...

True!

In my defense, though, now that I know what the problem was I can also
come up with a workaround.

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
J French

2005-01-28, 8:59 am

On Thu, 27 Jan 2005 18:25:41 GMT, NOSPAMFORdaniel_ahorn@yahoo.com
(Danny) wrote:


<snip>

>The MVPs stormtroopers ;o) patrolling these groups are very vigilant
>when it comes to (what they consider) inappropriate cross and
>multi-posting. So, either they're slacking off or they found my
>crosspost acceptable.


It is Multi-posting that is loathed

Cross-posting is fine - provided the NGs are relevant

The reason why Mult-posting is loathed is because one can spend some
time anwering a question in one NG, only to get to the next NG and
find that it has already been answered
Sam Hobbs

2005-01-28, 4:01 pm


"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41f92f72.7829463@News.Individual.NET...
>
> In my defense, though, now that I know what the problem was I can also
> come up with a workaround.


I am not sure I understand what you are saying but I probably understand
well enough. Perhaps another way to say what you saying is that it is often
much easier to ask a question when we know the answer.

There are a few fundamental techniques that can save a lot of time. For
example, as I said before, if we check for error values returned from
functions then we know we need to diagnose that problem first.


Sam Hobbs

2005-01-28, 4:01 pm

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41f92f38.7771505@News.Individual.NET...
>
> Well, according to that I should've given up at the first sign of
> trouble. Instead, I tried various approaches and only when I was at
> the end of my tether I asked for second opinion.


What I meant is that when a function complains (returns an error) then we
should not allow the program to continue if it uses data that depends on
it's (the first function's) success.

I did not mean that it is foolish to continue diagnosing and solving the
problem; I just meant that the diagnostics need to start with the first
function that returns an error.


Danny

2005-01-28, 9:00 pm

Date: Fri, 28 Jan 2005 08:27:51 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>
>What I meant is that when a function complains (returns an error) then we
>should not allow the program to continue if it uses data that depends on
>it's (the first function's) success.


Yes, of course, but there's no point in writing an error wrapper first
and worrying about the rest of the program before even knowing what
the problem is or whether the function can even be used? It's a
question of priorities.

That's like going to ER with a gaping wound only to be told I first
need to go and wash my clothes because they're covered with blood...

>I did not mean that it is foolish to continue diagnosing and solving the
>problem; I just meant that the diagnostics need to start with the first
>function that returns an error.


Which is exactly what I did, instead of worrying about error handling.
First things first.

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Danny

2005-01-28, 9:00 pm

Date: Fri, 28 Jan 2005 09:47:37 +0000 (UTC)
Name: erewhon@nowhere.uk (J French)

>Cross-posting is fine - provided the NGs are relevant


There was one suggestion that only "winapi" may have been relevant.
However, I don't think Xposting in "syntax" and "general" was over the
top in this case. Was it?

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Sam Hobbs

2005-01-29, 3:57 am

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41fa979c.12698184@News.Individual.NET...
>
> That's like going to ER with a gaping wound only to be told I first
> need to go and wash my clothes because they're covered with blood...


What I am trying to say is that we want to avoid going to the ER. If we
catch errors before they break our program, then they are easier to diagnose
and solve. If you consider error checking to be secondary to other
diagnotics, you will continue to encounter fatal programs.


J French

2005-01-29, 8:57 am

On Fri, 28 Jan 2005 19:55:18 GMT, NOSPAMFORdaniel_ahorn@yahoo.com
(Danny) wrote:

>Date: Fri, 28 Jan 2005 09:47:37 +0000 (UTC)
>Name: erewhon@nowhere.uk (J French)
>
>
>There was one suggestion that only "winapi" may have been relevant.
>However, I don't think Xposting in "syntax" and "general" was over the
>top in this case. Was it?


Not in my book
- it is when one gets links to C NGs that it gets annoying
- or even alt.rec.woodwork
Danny

2005-01-30, 3:58 pm

Date: Fri, 28 Jan 2005 17:46:07 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>
>What I am trying to say is that we want to avoid going to the ER. If we
>catch errors before they break our program, then they are easier to diagnose
>and solve. If you consider error checking to be secondary to other
>diagnotics, you will continue to encounter fatal programs.


I'm sorry, Sam, but you're completely missing the point here.

I knew *where* the problem was all along! Error checking would not
have told me anything new nor contributed anything to solving it.

Facts: A call has failed. I single stepped down to that point
examining, along the way, both the error codes and data returned by
all previous calls. All that checked out, as I wrote initially, and as
proof of that I provided the dump of data previous calls returned.

There is no point adding wads of error checking after this call if the
call itself doesn't work!

There is no point adding wads of error checking to earlier calls (in
this *test* code) if I'm single stepping and checking everything
manually!

There is no point adding wads of error checking to posted code and
obscuring the question if, as I explicitly said, I've checked the
program flow manually up to that point and provided the output!

I'm sorry, but continuing to focus on error checking instead of
answering the question *why* the call failed is totally beside the
point and didn't contribute anything to my finding the answer.

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Sam Hobbs

2005-01-31, 4:00 am

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41fd2344.5502078@News.Individual.NET...
>
> I'm sorry, Sam, but you're completely missing the point here.


What point? I think if the "point" had been clear enough I would not have
missed it.

> I knew *where* the problem was all along! Error checking would not
> have told me anything new nor contributed anything to solving it.
>
> Facts: A call has failed. I single stepped down to that point
> examining, along the way, both the error codes and data returned by
> all previous calls. All that checked out, as I wrote initially, and as
> proof of that I provided the dump of data previous calls returned.



Note that when I read your initial question, it had been a year or two since
I had written code using VerQueryValue. I did not understand a lot of what
was said in the original question and the dump had no value at the time.

> There is no point adding wads of error checking after this call if the
> call itself doesn't work!
>
> There is no point adding wads of error checking to earlier calls (in
> this *test* code) if I'm single stepping and checking everything
> manually!
>
> There is no point adding wads of error checking to posted code and
> obscuring the question if, as I explicitly said, I've checked the
> program flow manually up to that point and provided the output!


Yes, wads of error checking is unnecessary. Just use enough error checking
such that it is 90% of the program.

Just kidding; don't take that seriously.

> I'm sorry, but continuing to focus on error checking instead of
> answering the question *why* the call failed is totally beside the
> point and didn't contribute anything to my finding the answer.


I think if you read what I said, there is very little, if anything, that is
worth complaining about. I really think you were too quick to complain and
resisted admitting what the problems were. I know I answered the question
*why* the call failed; you just don't want to admit the mistakes.

There were at least three problems with the call to VerQueryValue.

(1) You used double backslashes instead of single backslashes.

(2) You used the wrong lang-codepage value (I am not sure about that, but my
guess is that the value you were using was incorrect).

(3) You used "lpVersion" for the address of the version value pointer buffer
instead of "VarPtr(lpVersion)".

Instead of admitting those problems, you that the declare for the
VerQueryValue address of the pointer parameter was incorrect. The declare
was correct if you used "VarPtr(lpVersion)".

So I posted working code. It seems strange to me that you would imply I did
not answer the question *why* the call failed.

I forget why I made the comment I did about checking errors, but I don't
recall saying much that was specific about your situation. Perhaps you
expected me to be wrong and were too quick to complain. I said things about
not continuing after an error is encountered and if you had just said that
that is what you did, then things would have not continued from there.
Instead you wanted to disagree.


Danny

2005-01-31, 4:01 pm

Date: Sun, 30 Jan 2005 17:25:07 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>
>What point? I think if the "point" had been clear enough I would not have
>missed it.


You managed quite masterfully. The point was very clear all along: How
do I make this call work? A hint: reading the Subject often helps.

>Note that when I read your initial question, it had been a year or two since
>I had written code using VerQueryValue. I did not understand a lot of what
>was said in the original question and the dump had no value at the time.


Which then begs the obvious question...

And it explains your inability to locate the problem.

>I think if you read what I said, there is very little, if anything, that is
>worth complaining about. I really think you were too quick to complain and
>resisted admitting what the problems were. I know I answered the question
>*why* the call failed; you just don't want to admit the mistakes.


Huh? I found the error myself and I said so! Are we reading the same
messages?

All you did is go on about error checking, code style (hello? this is
*test* code) and complain about cross posting (which nobody else seems
to mind).

Contrast that to Karl's response with working code. After comparing it
to mine I was able to locate the problem within minutes and then
promptly reported it here.

>There were at least three problems with the call to VerQueryValue.
>
>(1) You used double backslashes instead of single backslashes.


Irrelevant. The way the call was defined, using single backslashes
would've made no difference whatsoever (as I found out because I tried
all permutations, single and double).

>(2) You used the wrong lang-codepage value (I am not sure about that, but my
>guess is that the value you were using was incorrect).


Incorrect guesswork. But even if it were correct: See above.

>(3) You used "lpVersion" for the address of the version value pointer buffer
>instead of "VarPtr(lpVersion)".


Which you did *NOT* mention at all! (I just re-read your original
reply which I strongly advise you do as well.)

Only *AFTER* I found the problem myself and reported it, did you
piggy-back with a "me-too" comment offering an "alternative" solution.


Of course, once I found the problem, *anyone* could've come up with
many alternate solutions.

>Instead of admitting those problems, you that the declare for the
>VerQueryValue address of the pointer parameter was incorrect. The declare
>was correct if you used "VarPtr(lpVersion)".


Which you did *NOT* write in your original reply. If you did (instead
of unwarranted condescending remarks) we would not have this
discussion.

>So I posted working code. It seems strange to me that you would imply I did
>not answer the question *why* the call failed.


You did *NOT* answer why. Only *AFTER* I myself answered why, did you
comment with alternate code. => Check the thread!! <=

Anyway, I've got better things to do, so I think I'll just follow
Tony's lead (apparently, you do this often) and wrap it up with what
he said: "Have it your way...".

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Sam Hobbs

2005-02-01, 9:01 am

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41fe65ef.6117883@News.Individual.NET...
>
> And it explains your inability to locate the problem.


I thought you wanted a solution, which I did provide.

I said I was unfamiliar with the functions at the time I first read your
original question. I am sorry I did not make it clear, but I took your
original code, converted it to C++, refered to some code I had from when I
was working with it, then I replied. I am sorry I did not have a working VB
sample then, but I spent too much time on it. I obviously should not have.

Then when you made your comment about the parameter being specified
incorrectly in the function declaration, I did create a working VB sample
and posted it.

> Huh? I found the error myself and I said so! Are we reading the same
> messages?


No, you did not find the error. You found something to blame.

> All you did is go on about error checking, code style (hello? this is
> *test* code) and complain about cross posting (which nobody else seems
> to mind).


Yes, most everyone else ignored your question. The only other answer you got
was vague.

> Contrast that to Karl's response with working code. After comparing it
> to mine I was able to locate the problem within minutes and then
> promptly reported it here.


Then why was it necessary for you to continue here? You did not have to. To
whatever extent I am to blame, you are at blame just as much.

Note that my solution does not require that the VS_FIXEDFILEINFO be parsed;
my solution more closely resembles your original code.

> Irrelevant. The way the call was defined, using single backslashes
> would've made no difference whatsoever (as I found out because I tried
> all permutations, single and double).


You are right that double backslashes work the same as single backslashes.

> Which you did *NOT* mention at all! (I just re-read your original
> reply which I strongly advise you do as well.)
>
> Only *AFTER* I found the problem myself and reported it, did you
> piggy-back with a "me-too" comment offering an "alternative" solution.


Correct, I did nt mention it in my first reply. However look in the sample I
posted, which is working VB code. It uses "VarPtr(lpVersion)" instead of
"lpVersion", showing that "ByVal lplpBuffer As Long" works. You had said it
was the problem. My working code shows it was not the problem; you just did
not use it properly.

> Of course, once I found the problem, *anyone* could've come up with
> many alternate solutions.


No, because the problem you said was a problem was not a problem. My code
showed that.

> Which you did *NOT* write in your original reply. If you did (instead
> of unwarranted condescending remarks) we would not have this
> discussion.


I did post the code that uses "ByVal lplpBuffer As Long" in the declare
after you said it was the problem.

> You did *NOT* answer why. Only *AFTER* I myself answered why, did you
> comment with alternate code. => Check the thread!! <=


Yes, as I said, I posted working code after you said that "ByVal lplpBuffer
As Long" was the problem. However again, what you thought was a problem was
not a problem.

I went back to your original question and took your code again. I changed
the language code page thing from "040904E4" to "040904B0" and I changed
"lpVersion" to "VarPtr(lpVersion)". Then I added the code shown below to
convert the Byte array to a string. That works. So my first reply was wrong.

Dim VersionInfoBytes() As Byte
ReDim VersionInfoBytes(puVersionLen - 1)
CopyMemory VersionInfoBytes(0), ByVal lpVersion, puVersionLen
Text1 = StrConv(VersionInfoBytes, vbUnicode)


Danny

2005-02-01, 4:02 pm

Date: Tue, 1 Feb 2005 00:37:42 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>Yes, most everyone else ignored your question. The only other answer you got
>was vague.


Quite the contrary, as the following paragraph already stated (see
quote below).

Minutes after I saw Karl's response I reported that I found the
problem and the code is working. Your alternative solution was a
*comment* to this very message!

>
>Then why was it necessary for you to continue here? You did not have to. To
>whatever extent I am to blame, you are at blame just as much.


So, let's just agree to disagree agreeably. I'm sure we both have
better things to do.

I found a solution after examining Karl's code. Later on, you provided
an alternative. That's two for the price of one! Let's leave it at
that.

Danny

(You guessed it! ;o) Remove NOSPAMFOR before emailing.)
Sam Hobbs

2005-02-02, 4:02 pm

"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
news:41ffb19e.5022240@News.Individual.NET...
>
> So, let's just agree to disagree agreeably. I'm sure we both have
> better things to do.


I admit that I am vulnerable to getting caught up by people that refuse to
admit a mistake. Perhaps that did not happen here and it is my fault for
thinking it did.

There are far too many people that try to avoid saying they made a mistake
or something like that and instead say things that are more innacurate or
bizarre. I don't continue to ensure accuracy unless someone continues to say
things that are more innacurate or bizarre. When something is innacurate, I
simply state what is accurate. When the response is again innacurate or
bizarre, it is then that I get caught up in futility.

Again, if that is not what happened here, then I am sorry. If it did happen,
then it sure is foolish for me to continue.


Danny

2005-02-03, 4:02 pm

Date: Wed, 2 Feb 2005 09:18:49 -0800
Name: "Sam Hobbs" <samuel@social.rr.com_change_social_to_socal>

>"Danny" <NOSPAMFORdaniel_ahorn@yahoo.com> wrote in message
>news:41ffb19e.5022240@News.Individual.NET...
>

.... cut ...
>Again, if that is not what happened here, then I am sorry. If it did happen,
>then it sure is foolish for me to continue.


There's absolutely no need to apologize for anything, Sam. As I said
up front, I'm very grateful that you did take the time to respond.

In the end, I got two solutions "for the price of one" and that's a
win-win. It benefited not only me but hopefully anyone else interested
in the subject to see two approaches to the same problem.

Danny

(You guessed it! Remove NOSPAMFOR before emailing.)
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com