Disiance
Mar 10th, 2007, 01:14 PM
I'm trying to include an auto-update feature in my app. Basically, the app downloads a small EXE, which it then runs. The new EXE is the updater itself, which then downloads the program updates and installs them. This updater then restarts the program.
I'm having no problems whatsoever downloading the updater EXE (~66kb), but the actual program update (~366kb) is sometimes corrupt on some machines. The server ends up closing the connection before all of the data is received. A test I just ran on one of the machines messing up the download ended with these results:
1st Try: ~355kb downloaded
2nd Try: ~347kb downloaded
Anyone know why this may be happening? (code is below)
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String) As Long
Private responseBuffer As String
Private Sub Form_Load()
frmMain.Show
lblCaption.Caption = "Initializing"
Sleep 500
lblCaption.Caption = "Connecting to server"
DownloadFiles
End Sub
Private Sub DownloadFiles()
'Connect
sckConnect.Connect
DoEvents
Do Until sckConnect.State = sckConnected Or sckConnect.State = sckError
DoEvents
Loop
'Check for error
If sckConnect.State = sckError Then
MsgBox "There was an error connecting."
sckConnect.Close
DoEvents
End
End If
lblCaption.Caption = "Downloading file 1 of 1"
Dim dlFile As String
'Request update file
sckConnect.SendData "GET /updates/1_4/program.exe HTTP/1.1" & vbCrLf
sckConnect.SendData "Accept: *.*" & vbCrLf
sckConnect.SendData "User-Agent: Autoupdate" & vbCrLf
sckConnect.SendData "Host: www.myhost.com" & vbCrLf
sckConnect.SendData "Connection: close" & vbCrLf
sckConnect.SendData vbCrLf
Do Until sckConnect.State = sckClosed
DoEvents
Loop
'Check for non-200 response
If InStr(1, responseBuffer, "HTTP/1.1 200") = 0 Then
MsgBox "File not found."
End
End If
'Parse file
Dim contentLengthStart As Integer
Dim fileLength As Double
contentLengthStart = InStr(1, responseBuffer, "Content-Length:") + 15
fileLength = Int(Mid(responseBuffer, contentLengthStart, InStr(contentLengthStart, responseBuffer, Chr(10)) - contentLengthStart))
Dim appPath As String
appPath = App.Path
If Not Right(appPath, 1) = "\" Then appPath = appPath & "\"
If Len(Dir(appPath & "program_exe.bak")) > 0 Then Kill appPath & "program_exe.bak"
MoveFile appPath & "program.exe", appPath & "program_exe.bak"
Open appPath & "program.exe" For Output As #1
Print #1, Right(responseBuffer, fileLength)
Close #1
pbProgress.Value = pbProgress.Max
MsgBox "Update complete."
Shell appPath & "program.exe"
End
End Sub
Private Sub sckConnect_Close()
sckConnect.Close
DoEvents
End Sub
Private Sub sckConnect_DataArrival(ByVal bytesTotal As Long)
Dim dataBuffer As String
sckConnect.GetData dataBuffer
responseBuffer = responseBuffer & dataBuffer
pbProgress.Value = Len(responseBuffer)
End Sub
I'm having no problems whatsoever downloading the updater EXE (~66kb), but the actual program update (~366kb) is sometimes corrupt on some machines. The server ends up closing the connection before all of the data is received. A test I just ran on one of the machines messing up the download ended with these results:
1st Try: ~355kb downloaded
2nd Try: ~347kb downloaded
Anyone know why this may be happening? (code is below)
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String) As Long
Private responseBuffer As String
Private Sub Form_Load()
frmMain.Show
lblCaption.Caption = "Initializing"
Sleep 500
lblCaption.Caption = "Connecting to server"
DownloadFiles
End Sub
Private Sub DownloadFiles()
'Connect
sckConnect.Connect
DoEvents
Do Until sckConnect.State = sckConnected Or sckConnect.State = sckError
DoEvents
Loop
'Check for error
If sckConnect.State = sckError Then
MsgBox "There was an error connecting."
sckConnect.Close
DoEvents
End
End If
lblCaption.Caption = "Downloading file 1 of 1"
Dim dlFile As String
'Request update file
sckConnect.SendData "GET /updates/1_4/program.exe HTTP/1.1" & vbCrLf
sckConnect.SendData "Accept: *.*" & vbCrLf
sckConnect.SendData "User-Agent: Autoupdate" & vbCrLf
sckConnect.SendData "Host: www.myhost.com" & vbCrLf
sckConnect.SendData "Connection: close" & vbCrLf
sckConnect.SendData vbCrLf
Do Until sckConnect.State = sckClosed
DoEvents
Loop
'Check for non-200 response
If InStr(1, responseBuffer, "HTTP/1.1 200") = 0 Then
MsgBox "File not found."
End
End If
'Parse file
Dim contentLengthStart As Integer
Dim fileLength As Double
contentLengthStart = InStr(1, responseBuffer, "Content-Length:") + 15
fileLength = Int(Mid(responseBuffer, contentLengthStart, InStr(contentLengthStart, responseBuffer, Chr(10)) - contentLengthStart))
Dim appPath As String
appPath = App.Path
If Not Right(appPath, 1) = "\" Then appPath = appPath & "\"
If Len(Dir(appPath & "program_exe.bak")) > 0 Then Kill appPath & "program_exe.bak"
MoveFile appPath & "program.exe", appPath & "program_exe.bak"
Open appPath & "program.exe" For Output As #1
Print #1, Right(responseBuffer, fileLength)
Close #1
pbProgress.Value = pbProgress.Max
MsgBox "Update complete."
Shell appPath & "program.exe"
End
End Sub
Private Sub sckConnect_Close()
sckConnect.Close
DoEvents
End Sub
Private Sub sckConnect_DataArrival(ByVal bytesTotal As Long)
Dim dataBuffer As String
sckConnect.GetData dataBuffer
responseBuffer = responseBuffer & dataBuffer
pbProgress.Value = Len(responseBuffer)
End Sub