Das gibts zwar schon zur genüge (unter anderem auch irgendwo von mir ohne API), aber keine der Lösungen war für mich brauchbar.
1.) Ich will keine extra update.exe o.ä.
2.) Der Check und der Download muß auch über einen Proxy funktionieren und auch umgeleitete URLs verarbeiten können (Viele Kundennetzwerke gehen über einen Proxy ins Inet)
3.) Möglichst simpel.
4.) Threadsafe ohne Threadsafe
5.) Unicodefähig
Da sich Punkt 2 und Punkt 3 als APIlose Variante widersprechen, gibt es also eine Winonly API-Variante.
Vorraussetzung ist eigentlich nur, dass der Kunde seinen IE richtig konfiguriert hat. Kommt er mit dem ins Inet, dann klappt auch die API-Variante (inklusive Proxy und redirects).
Das ganze wird auch jeweils in einen Thread gesteckt, damit das Hauptprogramm von evtl. erhängten Servern nix mitkriegt.
Nach dem Beenden, wird eine Message an die Hauptqueue geschickt.
Naja, schaut es euch einfach an, hier die Hauptinclude:
Code: Alles auswählen
;/-----------------
;|
;| CheckForUpdates.pbi
;| V1.05 [01.06.2010]
;|
;| ©HeX0R 2009/2010
;|
;| Small include, which should make it
;| very easy, to give your applications
;| the power of an
;| Online Update
;|
;| for PB >= 4.0 (no DEMO)
;|
;| Needs the freely available
;| Online-Update-Creat0r
;| to create the online-info-files
;| (Just run example to get it)
;|
;| New since 1.04:
;| Error handling
;| (and also auto error logging)
;/-----------------
#CFU_IDENT = $6f3bc31a
Structure _CFU_VERSION_INFO_
Name.s ;Name of your Program
Version.s ;Version as String (for example "1.05.12")
URL.s ;Link, where Patch can be downloaded
FileSize.q ;Filesize of the patch
ReleaseDate.l ;Releasedate of the patch (unix timestamp)
MD5.s ;MD5 FileFingerprint of Patchfile
ServerFileName.s ;Real name of the Patch (if it is redirected for example)
InfoLink.s ;Link, to get further information
Text.s[3] ;Optional Texts, you maybe need
Number.l[3] ;Optional Long-Variables (for example used as Flags)
*Description ;Description of this update
EndStructure
Structure _CFU_THREAD_VALUES_
*URL
AuthMode.i
BlockSize.i
WindowHandle.i
Message.i
FileHandle.i
FileSize.q
StatusGadget.i
*Result
EndStructure
Structure _CFU_CallBack_Cookie_
*Buffer
Pointer.i
EndStructure
#CFU_NO_AUTH = $00
#CFU_VERSIONINFO_AUTH = $01
#CFU_FILEDOWNLOAD_AUTH = $02
Enumeration
#CFU_ERROR_NO_ERROR
#CFU_ERROR_CANT_CREATE_FILE
#CFU_ERROR_CANT_CREATE_THREAD
#CFU_ERROR_NO_MEMORY
#CFU_ERROR_NO_INTERNET
#CFU_ERROR_UNABLE_TO_OPEN_URL
#CFU_ERROR_UNABLE_TO_READ_ONLINEFILE
#CFU_ERROR_EMPTY_INFOFILE
#CFU_ERROR_NO_INFOFILE
EndEnumeration
CompilerIf Defined(CFU_LOG_ERROR, #PB_Constant) = 0
#CFU_LOG_ERROR = #True
CompilerEndIf
Prototype CFU_ErrorHandlerPrototype(ErrorNr)
Global *CFU_AuthBuffer
Global CFU_AuthBufferLength
Global CFU_AuthMode
Global CFU_LastError
Global CFU_ErrorHandler.CFU_ErrorHandlerPrototype = #False
Procedure CFU_InitErrorHandler(*Proc)
CFU_ErrorHandler = *Proc
EndProcedure
Procedure CFU_GetLastError()
Protected A = #CFU_ERROR_NO_ERROR
Swap A, CFU_LastError
ProcedureReturn A
EndProcedure
CompilerIf Defined(CFU_GetErrorMessage, #PB_Procedure) = 0
Procedure.s CFU_GetErrorMessage(Error = #PB_Default)
Protected Result.s = "No Error", Msg.s
If Error = #PB_Default
Error = CFU_GetLastError()
EndIf
Msg = Space(1024)
Select Error
Case #CFU_ERROR_CANT_CREATE_FILE
Result = "Unable to create File"
Case #CFU_ERROR_CANT_CREATE_THREAD
Result = "Unable to create Thread"
Case #CFU_ERROR_NO_MEMORY
Result = "Not enough Memory"
Case #CFU_ERROR_NO_INTERNET
Result = "WinINet-Init failed"
If FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, @Msg, 1024, 0)
Result + #CRLF$ + Msg
EndIf
Case #CFU_ERROR_UNABLE_TO_OPEN_URL
Result = "Unable to connect to URL"
If FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, @Msg, 1024, 0)
Result + #CRLF$ + Msg
EndIf
Case #CFU_ERROR_UNABLE_TO_READ_ONLINEFILE
Result = "Unable to open File on Server"
If FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, @Msg, 1024, 0)
Result + #CRLF$ + Msg
EndIf
Case #CFU_ERROR_EMPTY_INFOFILE
Result = "This seems to be an empty infofile"
Case #CFU_ERROR_NO_INFOFILE
Result = "The infofile doesn't exist on server!"
EndSelect
ProcedureReturn Result
EndProcedure
CompilerEndIf
Procedure CFU_LogError()
Protected FID, Error
If #CFU_LOG_ERROR
Error = CFU_GetLastError()
If Error <> #CFU_ERROR_NO_ERROR
If CFU_ErrorHandler
CFU_ErrorHandler(Error)
Else
If FileSize(GetEnvironmentVariable("APPDATA") + "\C4U\") <> -2
CreateDirectory(GetEnvironmentVariable("APPDATA") + "\C4U\")
EndIf
FID = OpenFile(#PB_Any, GetEnvironmentVariable("APPDATA") + "\C4U\ErrorLog.txt")
If FID
FileSeek(FID, Lof(FID))
WriteStringN(FID, FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss ", Date()) + CFU_GetErrorMessage(Error))
CloseFile(FID)
EndIf
EndIf
EndIf
EndIf
EndProcedure
Procedure CFU_Editor_StreamCallback(*dwCookie._CFU_CallBack_Cookie_, *pbBuff, cb, *pcb.LONG)
Protected Length
;/------
;| Callback used for CFU_Editor_Load()
;/------
Length = MemorySize(*dwCookie\Buffer) - *dwCookie\Pointer
If Length > cb
CopyMemory(*dwCookie\Buffer + *dwCookie\Pointer, *pbBuff, cb)
*pcb\l = cb
Else
If Length
CopyMemory(*dwCookie\Buffer + *dwCookie\Pointer, *pbBuff, Length)
EndIf
*pcb\l = Length
EndIf
*dwCookie\Pointer + *pcb\l
ProcedureReturn 0
EndProcedure
Procedure CFU_Editor_Load(Gadget, *Buffer)
Protected Stream.EDITSTREAM, C._CFU_CallBack_Cookie_
;/------
;| Procedure to get rtf-Data into an EditorGadget
;/------
If *Buffer And MemorySize(*Buffer)
C\Pointer = 0
C\Buffer = *Buffer
Stream\dwCookie = @C
Stream\pfnCallback = @CFU_Editor_StreamCallback()
SendMessage_(GadgetID(Gadget), #EM_STREAMIN, #SF_RTF, @Stream)
EndIf
EndProcedure
Procedure CFU_GetHTTPFile(*B._CFU_THREAD_VALUES_)
Protected hINet, hData, Bytes, Size, DownloadedBytes, f.f
;/------
;| Procedure to download something from the internet.
;| We use the WinAPI, because it makes sure
;| it will also work, when the user is behind a proxy.
;| (and he/she configures his/her IE correctly)
;| and even redirected files will be catched.
;|
;| This procedure is called as thread, to make sure
;| there won't be any lags, when the host is not reachable
;| or something like this.
;|
;| This procedure can download directly into memory or in a file.
;| See CFU_LoadInternetFile (in file) and CFU_LoadVersionInfo (in memory)
;/-------
*B\Result = 0
Size = 0
hINet = InternetOpen_(?GVI_Agent, 0, 0, 0, 0)
If Not hInet
CFU_LastError = #CFU_ERROR_NO_INTERNET
Else
;INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE
If *B\AuthMode And *CFU_AuthBuffer And CFU_AuthBufferLength
hData = InternetOpenUrl_(hINet, *B\URL, *CFU_AuthBuffer, CFU_AuthBufferLength, $4000100, 0)
Else
hData = InternetOpenUrl_(hINet, *B\URL, 0, 0, $4000100, 0)
EndIf
If Not hData
CFU_LastError = #CFU_ERROR_UNABLE_TO_OPEN_URL
Else
If *B\BlockSize = 0
*B\BlockSize = 8192
EndIf
*B\Result = AllocateMemory(*B\BlockSize)
If Not *B\Result
CFU_LastError = #CFU_ERROR_NO_MEMORY
Else
Repeat
If InternetReadFile_(hData, *B\Result + Size, *B\BlockSize, @Bytes) = #False
FreeMemory(*B\Result)
*B\Result = 0
CFU_LastError = #CFU_ERROR_UNABLE_TO_READ_ONLINEFILE
Break
ElseIf *B\FileHandle = -1
Size + Bytes
*B\Result = ReAllocateMemory(*B\Result, Size + *B\BlockSize)
If Not *B\Result
CFU_LastError = #CFU_ERROR_NO_MEMORY
Break
EndIf
Else
If *B\StatusGadget <> -1 And IsGadget(*B\StatusGadget)
f = ((DownloadedBytes + Bytes) / *B\FileSize) * 100
SetGadgetState(*B\StatusGadget, f)
EndIf
If Bytes
WriteData(*B\FileHandle, *B\Result, Bytes)
DownloadedBytes + Bytes
EndIf
EndIf
Until Bytes = 0
EndIf
If *B\Result And *B\AuthMode And *CFU_AuthBuffer And CFU_AuthBufferLength
If CFU_AuthMode = #CFU_VERSIONINFO_AUTH Or (CFU_AuthMode & #CFU_FILEDOWNLOAD_AUTH And *B\AuthMode = #CFU_FILEDOWNLOAD_AUTH)
FreeMemory(*CFU_AuthBuffer)
*CFU_AuthBuffer = 0
CFU_AuthBufferLength = 0
CFU_AuthMode = #CFU_NO_AUTH
EndIf
EndIf
InternetCloseHandle_(hData)
EndIf
InternetCloseHandle_(hINet)
EndIf
If *B\FileHandle <> -1
CloseFile(*B\FileHandle)
EndIf
If *B\WindowHandle And *B\Message And IsWindow_(*B\WindowHandle)
PostMessage_(*B\WindowHandle, *B\Message, *B\Result, #Null)
EndIf
If *B\FileHandle <> -1 And *B\Result
FreeMemory(*B\Result)
EndIf
FreeMemory(*B\URL)
FreeMemory(*B)
CFU_LogError()
EndProcedure
Procedure CFU_CheckVersionInfo(*R._CFU_VERSION_INFO_, wparam, delete = #True)
Protected Size, i
;/------
;| After Versioninfo has been downloaded (CFU_LoadVersionInfo), you can feed
;| this procedure with the wParam-Value of the Event
;| If anything is correct, the CFU_VERSION_INFO-Structure will be filled
;| with the values.
;/------
If *R
If Not wparam
;No Info there, maybe an empty file?
CFU_LastError = #CFU_ERROR_EMPTY_INFOFILE
*R = 0
Else
If PeekL(wparam) <> #CFU_IDENT
;This is no correct Infofile!
CFU_LastError = #CFU_ERROR_NO_INFOFILE
*R = 0
Else
;Ok, lets fill the VERSION_INFO-Structure
Size + SizeOf(LONG)
*R\Name = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
*R\Version = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
*R\URL = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
*R\FileSize = PeekQ(wparam + Size)
Size + SizeOf(QUAD)
*R\ReleaseDate = PeekL(wparam + Size)
Size + SizeOf(LONG)
*R\MD5 = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
*R\ServerFileName = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
*R\InfoLink = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
For i = 1 To SizeOf(_CFU_VERSION_INFO_\Text) / SizeOf(STRING)
*R\Text[i - 1] = PeekS(wparam + Size, -1, #PB_UTF8)
Size + MemoryStringLength(wparam + Size, #PB_UTF8) + 1
Next i
For i = 1 To SizeOf(_CFU_VERSION_INFO_\Number) / SizeOf(LONG)
*R\Number[i - 1] = PeekL(wparam + Size)
Size + SizeOf(LONG)
Next i
;Check, if there is a description
If MemorySize(wparam) - Size > 0
*R\Description = AllocateMemory(MemorySize(wparam) - Size)
CopyMemory(wparam + Size, *R\Description, MemorySize(wparam) - Size)
Else
*R\Description = 0
EndIf
EndIf
EndIf
EndIf
If wparam And delete
;Normaly delete here, maybe someone wants to delete it later
FreeMemory(wparam)
EndIf
CFU_LogError()
ProcedureReturn *R
EndProcedure
Procedure CFU_LoadVersionInfo(Url.s, WindowHandle, Message, UserName.s = "", Password.s = "", AuthMode = #CFU_NO_AUTH)
Protected T, i, a$, b$, *B
Protected *TV._CFU_THREAD_VALUES_ = AllocateMemory(SizeOf(_CFU_THREAD_VALUES_))
;/------
;| Through CFU_LoadVersionInfo, you start the thread, which tries to
;| load the online versioninfo.
;| When the thread has finished, it will send the Message [Message] to [WindowHandle]
;| with wparam as Buffer.
;| This Buffer should then be sent to CFU_CheckVersionInfo(), to get the correct values.
;|
;| New since V1.03:
;| Username and Password for basic htaccess secured sites.
;| AuthMode is a combination of:
;| AuthMode = #CFU_NO_AUTH: Don't use Authorization
;| AuthMode = #CFU_VERSIONINFO_AUTH: Use Authorization when loading versioninfo
;| AuthMode = #CFU_FILEDOWNLOAD_AUTH: Use Authorization when loading patchfile
;/------
*TV\URL = AllocateMemory(StringByteLength(Url) + SizeOf(CHARACTER))
PokeS(*TV\URL, Url)
CFU_AuthBufferLength = 0
If *CFU_AuthBuffer
FreeMemory(*CFU_AuthBuffer)
EndIf
If AuthMode > #CFU_NO_AUTH And UserName
CFU_AuthMode = AuthMode
*B = AllocateMemory(StringByteLength(UserName + ":" + Password) + 1)
PokeS(*B, UserName + ":" + Password, -1, #PB_Ascii)
i = (Len(UserName) + Len(Password)) * 2
b$ = Space(i)
Base64Encoder(*B, MemorySize(*B), @b$, i * SizeOf(CHARACTER))
a$ = "Authorization: Basic " + PeekS(@b$, -1, #PB_Ascii)
FreeMemory(*B)
*CFU_AuthBuffer = AllocateMemory(StringByteLength(a$) + SizeOf(CHARACTER))
PokeS(*CFU_AuthBuffer, a$)
CFU_AuthBufferLength = Len(a$)
Else
CFU_AuthMode = #CFU_NO_AUTH
EndIf
*TV\WindowHandle = WindowHandle
*TV\Message = Message
*TV\BlockSize = 0
*TV\AuthMode = CFU_AuthMode & #CFU_VERSIONINFO_AUTH
*TV\FileHandle = -1
*TV\StatusGadget = -1
T = CreateThread(@CFU_GetHTTPFile(), *TV)
If Not T
FreeMemory(*TV\URL)
FreeMemory(*TV)
CFU_LastError = #CFU_ERROR_CANT_CREATE_THREAD
EndIf
CFU_LogError()
ProcedureReturn T
EndProcedure
Procedure CFU_LoadInternetFile(Url.s, DestinationFile.s, WindowHandle, Message, FileSize, StatusbarGadget = -1, BlockSize = $10000)
Protected T, FID
Protected *TV._CFU_THREAD_VALUES_
;/------
;| This procedure will download the patchfile to the destination
;/------
FID = CreateFile(#PB_Any, DestinationFile)
If Not FID
CFU_LastError = #CFU_ERROR_CANT_CREATE_FILE
Else
*TV = AllocateMemory(SizeOf(_CFU_THREAD_VALUES_))
*TV\URL = AllocateMemory(StringByteLength(Url) + SizeOf(CHARACTER))
PokeS(*TV\URL, Url)
*TV\WindowHandle = WindowHandle
*TV\Message = Message
*TV\BlockSize = BlockSize
*TV\AuthMode = CFU_AuthMode & #CFU_FILEDOWNLOAD_AUTH
*TV\FileHandle = FID
*TV\FileSize = FileSize
*TV\StatusGadget = StatusbarGadget
T = CreateThread(@CFU_GetHTTPFile(), *TV)
If Not T
FreeMemory(*TV\URL)
FreeMemory(*TV)
CloseFile(FID)
CFU_LastError = #CFU_ERROR_CANT_CREATE_THREAD
EndIf
EndIf
CFU_LogError()
ProcedureReturn T
EndProcedure
DataSection
;Mozilla/4.0 (compatible; ST)
GVI_Agent:
Data.l $697A6F4D, $2F616C6C, $20302E34, $6D6F6328, $69746170, $3B656C62, $29545320
Data.b 0
EndDataSection
Code: Alles auswählen
;/-------------
;| Example for the
;| CheckForUpdates.pbi
;|
;| Should be easy to understand
;| and also easy to integrate
;| in own applications.
;|
;| PB >= 4.0 (no DEMO)
;|
;| ©HeX0R 2009
;|
;| UPDATE !!21.05.2009!!
;| Now with auto url-detection
;| in Update-Description
;|
;| UPDATE !!17.09.2009!!
;| Updatewindow has its own
;| Callback
;|
;/-------------
XIncludeFile "..\CheckForUpdates.pbi"
InitNetwork()
#URL_OF_INFOFILE = "http://h3x0r.ath.cx/Sonstiges/example.dat"
;Our VersionInfo Variable
;-Integrate (Add Global variable)
Global VI._CFU_VERSION_INFO_
;-Integrate (Add new Events)
Enumeration #WM_APP + 2
#EVENT_VERSION_INFO_RECEIVED
#EVENT_DOWNLOAD_FINISHED
EndEnumeration
Enumeration
#Window_Main
;
;-Integrate (Add Window Constant)
;If you want to use the OpenWindow_NewUpdate-Procedure in your own prog
;you have to integrate the following Windowconstant into your main window enumeration:
#Window_NewUpdate
EndEnumeration
Enumeration
#Button_Start_Check
#Editor_0
;
;-Integrate (Add Gadget Constants)
;If you want to use the OpenWindow_NewUpdate-Procedure in your own prog
;you have to integrate the following Gadgetconstants into your main gadget enumeration:
#Button_Update_Load
#Button_Update_Link
#Button_Update_Close
#Editor_Update_Description
#ProgressBar_Update
EndEnumeration
;-Integrate following two Procedures
Procedure.s ByteRechner(dSize.d)
Protected Namen = $4B4D4754, i = 24, C.c, Result.s = "0"
If dSize > 0.0
While dSize > 1024 And i >= 0
dSize / 1024
C = (Namen >> i) & $FF
i - 8
Wend
Result = StrD(dSize, 2) + " " + Chr(C) + "Byte"
EndIf
ProcedureReturn Result
EndProcedure
Procedure NewUpdateWindow_CallBack(Window, Msg, wparam, lparam)
Protected StringBuffer.s, *el.ENLINK, txt.TEXTRANGE, w, h
Select Msg
Case #WM_NOTIFY
*el = lParam
If *el\nmhdr\idFrom = #Editor_Update_Description
If *el\nmhdr\code = #EN_LINK
If *el\msg = #WM_LBUTTONDOWN
StringBuffer = Space(1024)
txt\chrg\cpMin = *el\chrg\cpMin
txt\chrg\cpMax = *el\chrg\cpMax
txt\lpstrText = @StringBuffer
SendMessage_(*el\nmhdr\hwndFrom, #EM_GETTEXTRANGE, 0, txt)
If StringBuffer
If Left(LCase(StringBuffer), 3) = "www"
StringBuffer = "http://" + StringBuffer
EndIf
RunProgram(StringBuffer)
EndIf
EndIf
EndIf
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;/ New Update found Window Example
Procedure OpenWindow_NewUpdate(Parent = 0)
Protected i
OpenWindow(#Window_NewUpdate, 0, 0, 300, 350, "New update found!", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_WindowCentered, Parent)
CompilerIf #PB_Compiler_Version < 430
CreateGadgetList(WindowID(#Window_NewUpdate))
CompilerEndIf
SetWindowCallback(@NewUpdateWindow_CallBack(), #Window_NewUpdate)
TextGadget(#PB_Any, 5, 5, 100, 20, "Name:")
StringGadget(#PB_Any, 105, 3, 190, 22, VI\Name, #PB_String_ReadOnly)
TextGadget(#PB_Any, 5, 30, 100, 20, "Version:")
StringGadget(#PB_Any, 105, 28, 190, 22, VI\Version, #PB_String_ReadOnly)
TextGadget(#PB_Any, 5, 55, 100, 20, "ReleaseDate:")
StringGadget(#PB_Any, 105, 53, 190, 22, FormatDate("%dd.%mm.%yyyy %hh:%ii", VI\ReleaseDate), #PB_String_ReadOnly)
TextGadget(#PB_Any, 5, 80, 100, 20, "FileSize:")
StringGadget(#PB_Any, 105, 78, 190, 22, ByteRechner(VI\FileSize), #PB_String_ReadOnly)
TextGadget(#PB_Any, 5, 105, 100, 20, "Info:")
EditorGadget(#Editor_Update_Description, 5, 130, 290, 165, #PB_Editor_ReadOnly)
ButtonGadget(#Button_Update_Load, 5, 300, 70, 22, "Download", #PB_Button_Default)
If Left(LCase(VI\InfoLink), 7) = "http://"
ButtonGadget(#Button_Update_Link, 115, 300, 70, 22, "Info")
EndIf
ButtonGadget(#Button_Update_Close, 225, 300, 70, 22, "Close")
ProgressBarGadget(#ProgressBar_Update, 5, 325, 290, 20, 0, 100)
;Activate WordWrap in EditorGadget
SendMessage_(GadgetID(#Editor_Update_Description), #EM_SETTARGETDEVICE, 0, 0)
;Enable Auto URL-Detection
i = SendMessage_(GadgetID(#Editor_Update_Description), #EM_GETEVENTMASK, 0, 0)
SendMessage_(GadgetID(#Editor_Update_Description), #EM_SETEVENTMASK, 0, i | #ENM_LINK)
SendMessage_(GadgetID(#Editor_Update_Description), #EM_AUTOURLDETECT, #True, 0)
;Check, if there is any Description
If VI\Description
CFU_Editor_Load(#Editor_Update_Description, VI\Description)
FreeMemory(VI\Description)
EndIf
EndProcedure
Procedure MyCallBack(Window, Msg, wparam, lparam)
Protected Result = #PB_ProcessPureBasicEvents, StringBuffer.s, *el.ENLINK, txt.TEXTRANGE
;Here are our two new Window-events
;those Messages get sent through PostMessage, so you will see
;them also in your mainloop.
;But i decided to do it inside the callback because of two reasons:
;
; 1.) EventwParam() will be obsolete and removed someday (maybe)
; 2.) There is a bug, when user moves the window:
; http://www.purebasic.fr/english/viewtopic.php?t=36027
; So it is possible, that messages never will arrive
Select Msg
;-Integrate (Callback)
Case #EVENT_VERSION_INFO_RECEIVED
If CFU_CheckVersionInfo(@VI, wParam)
;Ok, we have some info!
;Now we should check if MV\Version is newer then our Version
;But as long as this is just an example, we go on and show the window
OpenWindow_NewUpdate(WindowID(#Window_Main))
EndIf
Case #EVENT_DOWNLOAD_FINISHED
If wParam
AddGadgetItem(#Editor_0, -1, "Download finished!, File should be here:")
AddGadgetItem(#Editor_0, -1, GetTemporaryDirectory() + VI\ServerFileName)
;Check integrity of downloaded file
If MD5FileFingerprint(GetTemporaryDirectory() + VI\ServerFileName) = VI\MD5
;Now run Patch (well, this time, this is no patch)
RunProgram(GetTemporaryDirectory() + VI\ServerFileName)
;Send close message to own Program
SendMessage_(WindowID(#Window_Main), #WM_CLOSE, #Null, #Null)
Else
AddGadgetItem(#Editor_0, -1, "File seems to be corrupted!")
EndIf
Else
AddGadgetItem(#Editor_0, -1, "Something went wrong with the download!")
EndIf
DisableGadget(#Button_Update_Load, 0)
EndSelect
ProcedureReturn Result
EndProcedure
Procedure main()
OpenWindow(#Window_Main, 0, 0, 400, 400, "VersionCheck-Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
CompilerIf #PB_Compiler_Version < 430
CreateGadgetList(WindowID(#Window_Main))
CompilerEndIf
SetWindowCallback(@MyCallBack(), #Window_Main)
ButtonGadget(#Button_Start_Check, 140, 5, 120, 22, "Start Check Now")
EditorGadget(#Editor_0, 5, 35, 390, 360)
;Main Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Window_Main
Break
;-Integrate (CloseWindow)
Case #Window_NewUpdate
CloseWindow(#Window_NewUpdate)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #Button_Start_Check
;Start the Check-Thread
CFU_LoadVersionInfo(#URL_OF_INFOFILE, WindowID(#Window_Main), #EVENT_VERSION_INFO_RECEIVED)
;We will get informed through a #EVENT_VERSION_INFO_RECEIVED Event, when info download is finished
;-Integrate (EventGadget)
;Integrate those three buttons into your main eventloop:
Case #Button_Update_Link
RunProgram(VI\InfoLink)
Case #Button_Update_Close
CloseWindow(#Window_NewUpdate)
Case #Button_Update_Load
;Start the download
If CFU_LoadInternetFile(VI\URL, GetTemporaryDirectory() + VI\ServerFileName, WindowID(#Window_Main), #EVENT_DOWNLOAD_FINISHED, VI\FileSize, #ProgressBar_Update)
;We will get informed through a #EVENT_DOWNLOAD_FINISHED Event, when file download is finished
DisableGadget(#Button_Update_Load, 1)
EndIf
EndSelect
EndSelect
ForEver
EndProcedure
main()
End
Er sollte relativ selbsterklärend sein.
Viel Spaß
[Edit]
...
[Edit2]
...
[Edit3]
Basic Authorization hinzugefügt
[Edit4]
Beispiel verändert.
Das Updatewindow bekommt nun seinen eigenen Callback, damit die URL-Klicks auch richtig hinhauen.
[Edit5]
Kleinen Fehler in der Include bereinigt