N
Nak
Hi there,
It's probably me being weird more than the function but I'm having
problems with it doing as it should.
I have a C++ application with 2 resources of custom types,
RT_INIFILE @ 2000 (INI file)
and
IDR_MSISETUP @ 3000 (MSI file)
The declaration of my UpdateResource call is as follows,
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, ByVal lpType
As String, ByVal lpID As Integer, ByVal wLanguage As Integer, ByVal lpData()
As Byte, ByVal cbData As Integer) As Integer
End Function
Right, so here's the problem. When calling the above method to update
the 2 resources I get no errors returned, unfortunately further inspection
using a resource viewer shows that the MSI file is being updated (although
the resource viewer has trouble reading the data) and the INI file is not
updated, but kind of modified, it becomes 2 resource files within an item
called 2000, 1 the original INI file and 1 the new updated file (strange).
Now if I try the above method by changing the lpID parameter to a string
it says it's worked, but hasn't, which is rather strange too. So I'm
beginning to wonder if I'm getting the declaration wrong or something, but
if that's the case how comes it even attempts to update? Anyway, this is my
code that updates the resource
--- Start of file ---
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.IO
Public Class resourceUpdater
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function BeginUpdateResource(ByVal pFileName As String, ByVal
bDeleteExistingResources As Boolean) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, ByVal lpType
As String, ByVal lpID As String, ByVal wLanguage As Integer, ByVal lpData()
As Byte, ByVal cbData As Integer) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function EndUpdateResource(ByVal hUpdate As IntPtr, ByVal
fDiscard As Boolean) As Boolean
End Function
Private cStrFileName As String
Public Function updateResourceFromBuffer(ByVal iType As String, ByVal iID As
Integer, ByVal iBuffer() As Byte) As Boolean
Dim pIPrUpdating As IntPtr = BeginUpdateResource(cStrFileName, False)
If (Not pIPrUpdating.Equals(IntPtr.Zero)) Then
If (UpdateResource(pIPrUpdating, iType, iID.ToString, 0, iBuffer,
iBuffer.Length) = 1) Then
If (EndUpdateResource(pIPrUpdating, False)) Then
Return (True)
Else
Throw New Exception("Failed to end updating of resource '" &
iID.ToString & "' of type '" & iType & "'.")
End If
Else
Throw New Exception("Failed to update resource '" & iID.ToString
& "' of type '" & iType & "'.")
End If
Else
Throw New Exception("Failed to begin updating resource '" &
iID.ToString & "' of type '" & iType & "'.")
End If
End Function
Public Shared Function fromFile(ByVal iFileName As String) As
resourceUpdater
If (File.Exists(iFileName)) Then
Dim pWRDResource As New resourceUpdater()
pWRDResource.cStrFileName = iFileName
Return (pWRDResource)
Else
Throw New FileNotFoundException("The Win32 resource file could not
be found.", iFileName)
End If
End Function
End Class
--- End of file ---
Not much too it really, to update my resources I'm calling it like this,
Dim pRUrUpdater As resourceUpdater =
resourceUpdater.fromFile("c:\fubar.exe")
Call pRUrUpdater.updateResourceFromBuffer("RT_MSIINSTALLER", 3000,
pBytMSIInstaller)
Call pRUrUpdater.updateResourceFromBuffer("RT_INIFILE", 2000,
pBytINIConfig)
Obviously the passed byte arrays contain the correct data, as I can see
in the resource viewer 1 of the INI files are correct, the other shouldn't
actually be there. The MSI installer seems to have been updated correctly
as I'm even extracting it from the executable again and then running it, but
the INI file is messing me arround.
Any tips on how to use this function or reasons as to why it isn't
working correctly? Thanks loads in advance, much appreciated!
Nick.
It's probably me being weird more than the function but I'm having
problems with it doing as it should.
I have a C++ application with 2 resources of custom types,
RT_INIFILE @ 2000 (INI file)
and
IDR_MSISETUP @ 3000 (MSI file)
The declaration of my UpdateResource call is as follows,
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, ByVal lpType
As String, ByVal lpID As Integer, ByVal wLanguage As Integer, ByVal lpData()
As Byte, ByVal cbData As Integer) As Integer
End Function
Right, so here's the problem. When calling the above method to update
the 2 resources I get no errors returned, unfortunately further inspection
using a resource viewer shows that the MSI file is being updated (although
the resource viewer has trouble reading the data) and the INI file is not
updated, but kind of modified, it becomes 2 resource files within an item
called 2000, 1 the original INI file and 1 the new updated file (strange).
Now if I try the above method by changing the lpID parameter to a string
it says it's worked, but hasn't, which is rather strange too. So I'm
beginning to wonder if I'm getting the declaration wrong or something, but
if that's the case how comes it even attempts to update? Anyway, this is my
code that updates the resource
--- Start of file ---
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.IO
Public Class resourceUpdater
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function BeginUpdateResource(ByVal pFileName As String, ByVal
bDeleteExistingResources As Boolean) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, ByVal lpType
As String, ByVal lpID As String, ByVal wLanguage As Integer, ByVal lpData()
As Byte, ByVal cbData As Integer) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function EndUpdateResource(ByVal hUpdate As IntPtr, ByVal
fDiscard As Boolean) As Boolean
End Function
Private cStrFileName As String
Public Function updateResourceFromBuffer(ByVal iType As String, ByVal iID As
Integer, ByVal iBuffer() As Byte) As Boolean
Dim pIPrUpdating As IntPtr = BeginUpdateResource(cStrFileName, False)
If (Not pIPrUpdating.Equals(IntPtr.Zero)) Then
If (UpdateResource(pIPrUpdating, iType, iID.ToString, 0, iBuffer,
iBuffer.Length) = 1) Then
If (EndUpdateResource(pIPrUpdating, False)) Then
Return (True)
Else
Throw New Exception("Failed to end updating of resource '" &
iID.ToString & "' of type '" & iType & "'.")
End If
Else
Throw New Exception("Failed to update resource '" & iID.ToString
& "' of type '" & iType & "'.")
End If
Else
Throw New Exception("Failed to begin updating resource '" &
iID.ToString & "' of type '" & iType & "'.")
End If
End Function
Public Shared Function fromFile(ByVal iFileName As String) As
resourceUpdater
If (File.Exists(iFileName)) Then
Dim pWRDResource As New resourceUpdater()
pWRDResource.cStrFileName = iFileName
Return (pWRDResource)
Else
Throw New FileNotFoundException("The Win32 resource file could not
be found.", iFileName)
End If
End Function
End Class
--- End of file ---
Not much too it really, to update my resources I'm calling it like this,
Dim pRUrUpdater As resourceUpdater =
resourceUpdater.fromFile("c:\fubar.exe")
Call pRUrUpdater.updateResourceFromBuffer("RT_MSIINSTALLER", 3000,
pBytMSIInstaller)
Call pRUrUpdater.updateResourceFromBuffer("RT_INIFILE", 2000,
pBytINIConfig)
Obviously the passed byte arrays contain the correct data, as I can see
in the resource viewer 1 of the INI files are correct, the other shouldn't
actually be there. The MSI installer seems to have been updated correctly
as I'm even extracting it from the executable again and then running it, but
the INI file is messing me arround.
Any tips on how to use this function or reasons as to why it isn't
working correctly? Thanks loads in advance, much appreciated!
Nick.