[Win]Internet-Updates für eure Programme

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

[Win]Internet-Updates für eure Programme

Beitrag von HeX0R »

Um einige Kundenprogramme besser pflegen zu können, brauchte ich eine vernünftige Online-Update Funktion.

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
Und hier ein Beispiel (ohne Auth):

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
Wenn ihr den Download-Button klickt, bekommt ihr automatisch den UpdateInfo-Creat0r zugeschickt, mit dem ihr dann eure Info-Dateien erstellen und hochladen könnt (inklusive einer evtl. Patch.exe o.ä.).

Bild

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
Zuletzt geändert von HeX0R am 01.06.2010 21:46, insgesamt 9-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

:allright:
Macht auf dem ersten Blick einen guten Eindruck!

Werde ich wohl in kürze mal praktisch testen

Gruß
Thomas

PS: Könnteste die "UpdateInfo_Creat0R.exe" zippen, oder mir sagen wie
ich die Meldung: ein nicht identifiziertes Programm bla bla weg bekomme?

Passiert bei Download einer Exe, bei Setups ist das ja unwichtig, aber so
nervt es schon :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

ts-soft hat geschrieben:PS: Könnteste die "UpdateInfo_Creat0R.exe" zippen, oder mir sagen wie
ich die Meldung: ein nicht identifiziertes Programm bla bla weg bekomme?
Rechtsklick -> Eigenschaften -> Tab Allgemein -> Ganz unten -> Sicherheit: Zulassen
(unter XP; müsste aber bei Vista ähnlich funktionieren)

Grüße ... Kiffi
Hygge
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Beitrag von HeX0R »

-zip entfernt-

Ich hatte es eigentlich ursprünglich als zip, wollte aber der Demo einen direkten Start ermöglichen.
Zuletzt geändert von HeX0R am 27.02.2009 11:24, insgesamt 2-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Danke Kiffi, aber hilft nicht (siehe Bild) :(
Bild
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

HeX0R hat geschrieben:-zip-

Ich hatte es eigentlich ursprünglich als zip, wollte aber der Demo einen direkten Start ermöglichen.
Hat damit anscheinend nichts zu tun, will grundsätzlich Authentisierung haben?
Vielleicht User-Modus für Vista in den Compileroptionen? Ich bin überfragt.

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Beitrag von HeX0R »

Hmm... ich werde das morgen mal an Frauchens Vista-Schlepptop testen.
Ist ja seltsam...
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

ts-soft hat geschrieben:Danke Kiffi, aber hilft nicht (siehe Bild) :(
bevor wir uns falsch verstehen. Meinst Du diese Meldung?
Bild

die kann ich hiermit abschalten:
Bild

@HeX0R: Sorry, für das Off-Topic. :oops:
Hygge
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

@Kiffi
Meine Dialoge sind hübscher und anders aufgeteilt (siehe oben), hab schon
das menschlich mögliche erlaubt :mrgreen:

Hab jetzt mal spasseshalber andere Exen per IE gedownloadet, ist
unproblematisch, diese scheint etwas besonders zu haben.

Vielleicht der PayPal Button?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Beitrag von HeX0R »

Mir ist heute Nacht noch eingefallen, dass ich dem Tool auch gleich eine automatische Update-Check-Funktion spendiert hatte.
Um mir ein extra Menü zu sparen, hab ich es einfach bei jedem Start aufgerufen.

Das hab ich jetzt mal ganz rausgemacht, nur um zu checken, ob Vista dann ruhig ist.
Aber was passiert dann, wenn man via FTP Daten hochladen will? Kommt dann nicht dieselbe Meldung?

Egal, hier extra mal für dich Thomas:
--entfernt--
@Kiffi:
Das ist kein Offtopic, zumindest sehe ich das nicht so, will schon wissen, was Vista da wieder zu meckern hat.
Zuletzt geändert von HeX0R am 21.01.2009 23:29, insgesamt 1-mal geändert.
Antworten