From: google on
Hi,

I need to update the file and product version numbers of EXEs and DLLs
written in VB6. After doing some research on the net and using some
examples written in C++ I've come up with the code below. When I run
it the return values of the API calls indicate that they succeeded but
the version number of my sample EXE remain unchanged. Can anyone tell
me what I'm doing wrong?

Option Explicit

Private Const RT_VERSION As Long = 16

Private Const LANG_NEUTRAL As Integer = &H0
Private Const LANG_ENGLISH As Long = &H9

Private Declare Function GetFileVersionInfoSize Lib "Version.dll"
Alias "GetFileVersionInfoSizeA" (ByVal lptstrFilename As String,
lpdwHandle As Long) As Long
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 BeginUpdateResource Lib "KERNEL32" Alias
"BeginUpdateResourceA" (ByVal pFileName As String, ByVal
bDeleteExistingResources As Long) As Long
Private Declare Function UpdateResource Lib "KERNEL32" Alias
"UpdateResourceA" (ByVal hUpdate As Long, ByVal lpType As Long, ByVal
lpName As Long, ByVal wLanguage As Long, lpData() As Byte, ByVal
cbData As Long) As Long
Private Declare Function EndUpdateResource Lib "KERNEL32" Alias
"EndUpdateResourceA" (ByVal hUpdate As Long, ByVal fDiscard As Long)
As Long

Private Sub UpdateFileVersion(ByVal vstrFilePath As String)

Dim llngHandle As Long
Dim llngVersionInfoLength As Long
Dim llngResult As Long
Dim lbytBuffer() As Byte
Dim llngResourceHandle As Long
Dim llngReturnValue As Long

llngVersionInfoLength = GetFileVersionInfoSize(vstrFilePath,
llngHandle)

If llngVersionInfoLength <> 0 Then
ReDim lbytBuffer(llngVersionInfoLength - 1)

llngResult = GetFileVersionInfo(vstrFilePath, 0,
llngVersionInfoLength, lbytBuffer(0))

If llngResult <> 0 Then
'QUICK AND DIRTY UPDATING OF VERSION NUMBER, JUST TO CHECK
IT WORKS

'UPDATE FILE VERSION NUMBER
lbytBuffer(50) = 5
lbytBuffer(48) = 6
lbytBuffer(54) = 7
lbytBuffer(52) = 8

'UPDATE PRODUCT VERSION NUMBER
lbytBuffer(58) = 5
lbytBuffer(56) = 6
lbytBuffer(62) = 7
lbytBuffer(60) = 8

llngResourceHandle = BeginUpdateResource(vstrFilePath, 0)

If llngResourceHandle <> 0 Then
llngReturnValue = UpdateResource(llngResourceHandle,
RT_VERSION, 1, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lbytBuffer,
llngVersionInfoLength)

If llngReturnValue = 0 Then
MsgBox "Unable to update resource (" &
Err.LastDllError & ")", vbExclamation, Me.Caption
End If

llngReturnValue =
EndUpdateResource(llngResourceHandle, 0)

If llngReturnValue <> 0 Then
MsgBox "Version number updated", vbInformation,
Me.Caption
Else
MsgBox "Unable to write updated resource (" &
Err.LastDllError & ")", vbExclamation, Me.Caption
End If
Else
MsgBox "Unable to retrieve resource update handle",
vbExclamation, Me.Caption
End If
Else
MsgBox "Unable to get file version info (" &
Err.LastDllError & ")", vbExclamation, Me.Caption
End If
Else
MsgBox "Unable to get file version info size (" &
Err.LastDllError & ")", vbExclamation, Me.Caption
End If

End Sub

Public Function MAKELANGID(ByVal vintPrimaryLanguage As Integer, ByVal
vintSubLanguage As Integer) As Long

MAKELANGID = (vintSubLanguage * 1024) Or vintPrimaryLanguage

End Function


As it says in the comments I intend to find a more elegant way of
setting the version numbers themselves but I'm just using a quick and
dirty method for now to check it works.

I realise that most of you in this group probably don't use VB6 but
any help would be greatly appreciated.

Thanks in advance,

Colin
From: Volodymyr M. Shcherbyna on
Use hex editors to see if the changes were flushed to file. And if not, you
will be able to see whats wrong. Also, you can use ResHack tool to analyze
resources.

--
Volodymyr, blog: http://www.shcherbyna.com/
(This posting is provided "AS IS" with no warranties, and confers no
rights)
<google(a)colinbaker.me.uk> wrote in message
news:2c4cdd5b-8220-4f77-96ac-007dbfb4e63a(a)f63g2000hsf.googlegroups.com...
> Hi,
>
> I need to update the file and product version numbers of EXEs and DLLs
> written in VB6. After doing some research on the net and using some
> examples written in C++ I've come up with the code below. When I run
> it the return values of the API calls indicate that they succeeded but
> the version number of my sample EXE remain unchanged. Can anyone tell
> me what I'm doing wrong?
>
> Option Explicit
>
> Private Const RT_VERSION As Long = 16
>
> Private Const LANG_NEUTRAL As Integer = &H0
> Private Const LANG_ENGLISH As Long = &H9
>
> Private Declare Function GetFileVersionInfoSize Lib "Version.dll"
> Alias "GetFileVersionInfoSizeA" (ByVal lptstrFilename As String,
> lpdwHandle As Long) As Long
> 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 BeginUpdateResource Lib "KERNEL32" Alias
> "BeginUpdateResourceA" (ByVal pFileName As String, ByVal
> bDeleteExistingResources As Long) As Long
> Private Declare Function UpdateResource Lib "KERNEL32" Alias
> "UpdateResourceA" (ByVal hUpdate As Long, ByVal lpType As Long, ByVal
> lpName As Long, ByVal wLanguage As Long, lpData() As Byte, ByVal
> cbData As Long) As Long
> Private Declare Function EndUpdateResource Lib "KERNEL32" Alias
> "EndUpdateResourceA" (ByVal hUpdate As Long, ByVal fDiscard As Long)
> As Long
>
> Private Sub UpdateFileVersion(ByVal vstrFilePath As String)
>
> Dim llngHandle As Long
> Dim llngVersionInfoLength As Long
> Dim llngResult As Long
> Dim lbytBuffer() As Byte
> Dim llngResourceHandle As Long
> Dim llngReturnValue As Long
>
> llngVersionInfoLength = GetFileVersionInfoSize(vstrFilePath,
> llngHandle)
>
> If llngVersionInfoLength <> 0 Then
> ReDim lbytBuffer(llngVersionInfoLength - 1)
>
> llngResult = GetFileVersionInfo(vstrFilePath, 0,
> llngVersionInfoLength, lbytBuffer(0))
>
> If llngResult <> 0 Then
> 'QUICK AND DIRTY UPDATING OF VERSION NUMBER, JUST TO CHECK
> IT WORKS
>
> 'UPDATE FILE VERSION NUMBER
> lbytBuffer(50) = 5
> lbytBuffer(48) = 6
> lbytBuffer(54) = 7
> lbytBuffer(52) = 8
>
> 'UPDATE PRODUCT VERSION NUMBER
> lbytBuffer(58) = 5
> lbytBuffer(56) = 6
> lbytBuffer(62) = 7
> lbytBuffer(60) = 8
>
> llngResourceHandle = BeginUpdateResource(vstrFilePath, 0)
>
> If llngResourceHandle <> 0 Then
> llngReturnValue = UpdateResource(llngResourceHandle,
> RT_VERSION, 1, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lbytBuffer,
> llngVersionInfoLength)
>
> If llngReturnValue = 0 Then
> MsgBox "Unable to update resource (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
>
> llngReturnValue =
> EndUpdateResource(llngResourceHandle, 0)
>
> If llngReturnValue <> 0 Then
> MsgBox "Version number updated", vbInformation,
> Me.Caption
> Else
> MsgBox "Unable to write updated resource (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
> Else
> MsgBox "Unable to retrieve resource update handle",
> vbExclamation, Me.Caption
> End If
> Else
> MsgBox "Unable to get file version info (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
> Else
> MsgBox "Unable to get file version info size (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
>
> End Sub
>
> Public Function MAKELANGID(ByVal vintPrimaryLanguage As Integer, ByVal
> vintSubLanguage As Integer) As Long
>
> MAKELANGID = (vintSubLanguage * 1024) Or vintPrimaryLanguage
>
> End Function
>
>
> As it says in the comments I intend to find a more elegant way of
> setting the version numbers themselves but I'm just using a quick and
> dirty method for now to check it works.
>
> I realise that most of you in this group probably don't use VB6 but
> any help would be greatly appreciated.
>
> Thanks in advance,
>
> Colin


From: Mihai N. on
> llngReturnValue = UpdateResource(llngResourceHandle,
> RT_VERSION, 1, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lbytBuffer,
> llngVersionInfoLength)

When you retrieved the versioninfo resource you did not take the
LANG_NEUTRAL, SUBLANG_DEFAULT one, so why write it there?
I can almost bet that when you dig into the result with a resource
editor you will find two versioninfo resources, one English and one
neutral.


--
Mihai Nita [Microsoft MVP, Visual C++]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
From: Kerem G�mr�kc� on
Hi Colin,

dont take this the wrong way, but
this sounds strange to me, changing
version number info inside a compiled
file. I mean, sure you have your reasons
for doing this, but why not compile a new
library/exe/sys or whatever and include new
version info,....?

I tell you this by thinking about e.g. stuff like
Checksums compiled into the binary and maybe
compared against calculated,..

Regards

Kerem

--
--
-----------------------
Beste Gr�sse / Best regards / Votre bien devoue
Kerem G�mr�kc�
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

<google(a)colinbaker.me.uk> schrieb im Newsbeitrag
news:2c4cdd5b-8220-4f77-96ac-007dbfb4e63a(a)f63g2000hsf.googlegroups.com...
> Hi,
>
> I need to update the file and product version numbers of EXEs and DLLs
> written in VB6. After doing some research on the net and using some
> examples written in C++ I've come up with the code below. When I run
> it the return values of the API calls indicate that they succeeded but
> the version number of my sample EXE remain unchanged. Can anyone tell
> me what I'm doing wrong?
>
> Option Explicit
>
> Private Const RT_VERSION As Long = 16
>
> Private Const LANG_NEUTRAL As Integer = &H0
> Private Const LANG_ENGLISH As Long = &H9
>
> Private Declare Function GetFileVersionInfoSize Lib "Version.dll"
> Alias "GetFileVersionInfoSizeA" (ByVal lptstrFilename As String,
> lpdwHandle As Long) As Long
> 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 BeginUpdateResource Lib "KERNEL32" Alias
> "BeginUpdateResourceA" (ByVal pFileName As String, ByVal
> bDeleteExistingResources As Long) As Long
> Private Declare Function UpdateResource Lib "KERNEL32" Alias
> "UpdateResourceA" (ByVal hUpdate As Long, ByVal lpType As Long, ByVal
> lpName As Long, ByVal wLanguage As Long, lpData() As Byte, ByVal
> cbData As Long) As Long
> Private Declare Function EndUpdateResource Lib "KERNEL32" Alias
> "EndUpdateResourceA" (ByVal hUpdate As Long, ByVal fDiscard As Long)
> As Long
>
> Private Sub UpdateFileVersion(ByVal vstrFilePath As String)
>
> Dim llngHandle As Long
> Dim llngVersionInfoLength As Long
> Dim llngResult As Long
> Dim lbytBuffer() As Byte
> Dim llngResourceHandle As Long
> Dim llngReturnValue As Long
>
> llngVersionInfoLength = GetFileVersionInfoSize(vstrFilePath,
> llngHandle)
>
> If llngVersionInfoLength <> 0 Then
> ReDim lbytBuffer(llngVersionInfoLength - 1)
>
> llngResult = GetFileVersionInfo(vstrFilePath, 0,
> llngVersionInfoLength, lbytBuffer(0))
>
> If llngResult <> 0 Then
> 'QUICK AND DIRTY UPDATING OF VERSION NUMBER, JUST TO CHECK
> IT WORKS
>
> 'UPDATE FILE VERSION NUMBER
> lbytBuffer(50) = 5
> lbytBuffer(48) = 6
> lbytBuffer(54) = 7
> lbytBuffer(52) = 8
>
> 'UPDATE PRODUCT VERSION NUMBER
> lbytBuffer(58) = 5
> lbytBuffer(56) = 6
> lbytBuffer(62) = 7
> lbytBuffer(60) = 8
>
> llngResourceHandle = BeginUpdateResource(vstrFilePath, 0)
>
> If llngResourceHandle <> 0 Then
> llngReturnValue = UpdateResource(llngResourceHandle,
> RT_VERSION, 1, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lbytBuffer,
> llngVersionInfoLength)
>
> If llngReturnValue = 0 Then
> MsgBox "Unable to update resource (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
>
> llngReturnValue =
> EndUpdateResource(llngResourceHandle, 0)
>
> If llngReturnValue <> 0 Then
> MsgBox "Version number updated", vbInformation,
> Me.Caption
> Else
> MsgBox "Unable to write updated resource (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
> Else
> MsgBox "Unable to retrieve resource update handle",
> vbExclamation, Me.Caption
> End If
> Else
> MsgBox "Unable to get file version info (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
> Else
> MsgBox "Unable to get file version info size (" &
> Err.LastDllError & ")", vbExclamation, Me.Caption
> End If
>
> End Sub
>
> Public Function MAKELANGID(ByVal vintPrimaryLanguage As Integer, ByVal
> vintSubLanguage As Integer) As Long
>
> MAKELANGID = (vintSubLanguage * 1024) Or vintPrimaryLanguage
>
> End Function
>
>
> As it says in the comments I intend to find a more elegant way of
> setting the version numbers themselves but I'm just using a quick and
> dirty method for now to check it works.
>
> I realise that most of you in this group probably don't use VB6 but
> any help would be greatly appreciated.
>
> Thanks in advance,
>
> Colin


From: google on
Thanks for all your replies.

I'll break out the hex editor and try to figure out what's going on,
although the file size remains unchanged which suggests it hasn't
added an extra resource.

Kerem - the reason I need to do this is to set all 4 parts of the
version number, VB lets you set major, minor and revision but not
build for some reason.

Colin