Check4Update API-Free

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: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Check4Update API-Free

Beitrag von HeX0R »

Moin,

bin gerade dabei, meine ganzen Code-Schnippsel fürs PB4 umzuwursten und dabei aus manchen Kniffen selbständige include-Dateien zusammenzustellen.

Macht es dann später einfacher es in irgendein Projekt einzubinden.

Das hier ist eine Prozedur, um euren Applikationen recht einfach eine Auto-Update-Funktion zu spendieren. Sie läuft völlig autark in einem Thread, bremst euer Proggy also auch nicht aus, wenn der Host, der das Update beinhaltet down ist oder gerade mit DOS-Attacks kämpft ;).
Es wurde gänzlich auf API verzichtet, um es auch für andere OS's nutzbar zu machen.

Dazu passende selbstlaufende Patches könnt ihr recht easy mit meinem PatchMaster erstellen.

Die eigentlich relevante Funktion ist C4U_CheckForUpdate(), die auch bestmöglich kommentiert sein sollte.
Man beachte auch den Head-Comment, der eigentlich alle Fragen beantworten sollte.

Hier die Check4Updates.pbi:

Code: Alles auswählen

;/-------------------------------------
;|
;| Check4Updates.pbi
;| -------------------------
;|
;| (c)HeX0R 2007 / http://h3x0r.ath.cx
;| Purebasic 4.0 (Demo supported)
;|
;| This Procedure will call a Thread
;| which will check if an update
;| for your application is available.
;| If it is available, the user can also
;| download it.
;|
;| Why as Thread ?
;| If the URL where the update-information
;| is set is temporarily down, your
;| application would hang on the
;| Connection-Try for a very long time.
;|
;| This Procedure is totaly without any API!
;|
;| Usage:
;| Create a File like this Example:
;| http://h3x0r.ath.cx/Sonstiges/WinRar.txt
;|
;| Upload it to some webspace
;|
;| Explanation of the Tags:
;|[VERSION][/VERSION]       -> Between these Tags your latest Version-Number
;|                             is set.
;|[LINK][/LINK]             -> OPTIONAL Parameter, you can set a Link
;|                             with more information to your update
;|[UPDATEFILE][/UPDATEFILE] -> Link to the download.
;|                             This can also be a php-site, which redirects
;|                             to the real download.
;|[INFOS][/INFOS]           -> OPTIONAL Paramater, you can give as many Infos
;|                             to your update as whished.
;|                             This Tag is the only one which can be used
;|                             over more then just one line.
;|[SFV][/SFV]               -> OPTIONAL Parameter, set the Result of
;|                             MD5FileFingerprint() between these Tags, to make
;|                             sure the downloaded file isn't corrupt.
;|                             If corrupt, the file will be deleted.
;|                             (And next time downloaded again)
;|
;| For further information check comments in the C4U_Init()-Procedure.
;|
;| For creating a self running Patch-File for your application you can use
;| the PatchMaster : http://h3x0r.ath.cx/download.php?view.34
;|
;|
;/---------------------------------------

;-Structures
Structure _C4U_SPECIAL_
	S.l[0]
EndStructure

Structure _C4U_UPDATE_STRUCTURE
	*Version
	*URL
	*PathToSaveFileTo
	*SFV
	*FileName
	*Link
	*LastTimeChecked.LONG
	*P._C4U_SPECIAL_
	Status.l
	Mode.l
	InitOK.b
	ThreadID.l
	MainWindowID.l
	WindowID.l
	TimeOUT.l
	LastError.l
	Phase.l
EndStructure

Global _C4U_._C4U_UPDATE_STRUCTURE

;-Constants
#C4U_START_BUFFER           = 32 * 1024
#C4U_READDATA_BLOCK         = 8192

#C4U_MODE_USE_DIALOG        = $01
#C4U_MODE_END_IF_UPDATE     = $02
#C4U_MODE_START_UPDATE      = $04
#C4U_MODE_START_IMMEDIATELY = $08

;-Error-Constants
Enumeration
	#C4U_NO_ERROR
	#C4U_UNABLE_TO_START_THREAD
	#C4U_NO_MEMORY_AVAILABLE
	#C4U_NOT_YET_INITIALIZED
	#C4U_PARAMETERS_FORGOTTEN
	#C4U_TIMED_OUT
	#C4U_UNABLE_TO_REACH_HOST
	#C4U_UNABLE_TO_CREATE_FILE
	#C4U_CORRUPTED_FILE
	#C4U_VERSION_FILE_NOT_FOUND
	#C4U_FILE_NOT_FOUND
	#C4U_UNSUPPORTED_SERVER
EndEnumeration

Procedure.l C4U_OpenUpdateWindow(*Buffer)
	Protected WinID.l, Version.l, Info.l, Download.l, Start.l, Link.l, Cancel.l, S.l, i.l

	WinID = OpenWindow(#PB_Any, 295, 243, 320, 245, "Update Found", #PB_Window_SystemMenu | #PB_Window_ScreenCentered, _C4U_\MainWindowID)
	If WinID And CreateGadgetList(WindowID(WinID))
		TextGadget(#PB_Any, 10, 10, 60, 20, "Version:")
		Version  = StringGadget(#PB_Any, 80, 10, 220, 20, "", #PB_String_ReadOnly)
		Info     = EditorGadget(#PB_Any, 80, 40, 220, 130, #PB_Editor_ReadOnly)
		TextGadget(#PB_Any, 10, 40, 60, 20, "Infos:")
		Download = ProgressBarGadget(#PB_Any, 10, 180, 290, 20, 0, 100, #PB_ProgressBar_Smooth)
		Start    = ButtonGadget(#PB_Any, 5, 220, 80 ,20 , "Start Update")
		Link     = ButtonGadget(#PB_Any, 120, 220, 80 ,20, "-Link-")
		Cancel   = ButtonGadget(#PB_Any, 235 , 220, 80 ,20, "Cancel")

		SetGadgetText(Version, PeekS(*Buffer + _C4U_\P\S[0], _C4U_\P\S[1]))
		S = _C4U_\P\S[6]
		For i = _C4U_\P\S[6] To _C4U_\P\S[6] + _C4U_\P\S[7] - 1
			If PeekB(*Buffer + i) = 10 Or PeekB(*Buffer + i) = 13
				AddGadgetItem(Info, -1, PeekS(*Buffer + S, i - S))
				S = i + 1
				If PeekB(*Buffer + S) = 13 Or PeekB(*Buffer + S) = 10
					S + 1
					i + 1
				EndIf
			ElseIf PeekW(*Buffer + i) = 'n\'
				AddGadgetItem(Info, -1, PeekS(*Buffer + S, i - S))
				S = i + 2
				i + 1
			EndIf
		Next i
		AddGadgetItem(Info, -1, PeekS(*Buffer + S, i - S))
		If _C4U_\P\S[2] = -1 Or _C4U_\P\S[3] = -1
			DisableGadget(Link, 1)
		EndIf
		StickyWindow(WinID, #True)
		_C4U_\P = 0

		Repeat
			Select WaitWindowEvent(20)
				Case 0
					SetGadgetState(Download, _C4U_\Status)
				Case #PB_Event_CloseWindow
					If EventWindow() = WinID
						_C4U_\Phase = 10
						CloseWindow(WinID)
						Break
					EndIf
				Case #PB_Event_Gadget
					Select EventGadget()
						Case Link
							RunProgram(PeekS(_C4U_\Link))
						Case Start
							DisableGadget(Start, 1)
							_C4U_\Phase + 1
						Case Cancel
							CloseWindow(WinID)
							_C4U_\Phase = 10
							Break
					EndSelect

			EndSelect
			If _C4U_\ThreadID = 0
				CloseWindow(WinID)
				Break
			EndIf
		ForEver

	EndIf

EndProcedure

Procedure.l C4U_FindString(*where, *what, Start_Pos.l, Length.l)

	;/-----------------------
	;| Function to find a string
	;| in Memory and
	;| Returning the Position
	;/-----------------------

	Protected Found.l = -1, Search_Length.l, i.l

	Search_Length = MemoryStringLength(*what)
	Length        = Length - Search_Length
	For i = Start_Pos To Length
		If CompareMemoryString(*where + i, *what, 1, Search_Length) = 0
			Found = i
			Break
		EndIf
	Next i
	ProcedureReturn Found
EndProcedure

Procedure.l C4U_Connect(*URL, Length.l)
	Protected *Buffer, *B.BYTE, NetID.l = 0, Start.l = 0, i.l, L.l, F.l, H.l

	*Buffer = AllocateMemory(Length + 1024)
	If CompareMemoryString(*URL, @"http://", 1, 7) = 0
		Start = 7
		Length - 7
	EndIf
	*B = *URL + Start
	F  = Length
	H  = 0
	For i = 0 To Length - 1
		If *B\b ='/'
			If F = Length
				F = i
			EndIf
			H = i
		EndIf
		*B + 1
	Next
	If F < Length
		NetID = OpenNetworkConnection(PeekS(*URL + Start, F), 80)
		If NetID
			L + MemoryStringLength(?C4U_GET_REQUEST_1)
			CopyMemory(?C4U_GET_REQUEST_1, *Buffer, L)
			CopyMemory(*URL + Start + F, *Buffer + L, Length - F)
			L + Length - F
			CopyMemory(?C4U_GET_REQUEST_2, *Buffer + L, MemoryStringLength(?C4U_GET_REQUEST_2))
			L + MemoryStringLength(?C4U_GET_REQUEST_2)
			CopyMemory(*URL + Start, *Buffer + L, F)
			L + F
			CopyMemory(?C4U_GET_REQUEST_3, *Buffer + L, MemoryStringLength(?C4U_GET_REQUEST_3))
			L + MemoryStringLength(?C4U_GET_REQUEST_3)
			If SendNetworkData(NetID,  *Buffer, L) = -1
				CloseNetworkConnection(NetID)
				NetID = 0
			EndIf
			If H > 0
				CopyMemory(*URL + Start + H + 1, _C4U_\FileName, Length - H - 1)
				PokeB(_C4U_\FileName + Length - H - 1, 0)
			EndIf
		EndIf
	EndIf
	FreeMemory(*Buffer)
	ProcedureReturn NetID

EndProcedure

Procedure.l C4U_Hex2Dec(*Buffer.BYTE)
	Protected Result.l = 0

	While *Buffer\b = 13 Or *Buffer\b = 10
		*Buffer + 1
	Wend

	Repeat
		If *Buffer\b >= '0' And *Buffer\b <= '9'
			Result = (Result << 4) | (*Buffer\b - '0')
		ElseIf *Buffer\b >= 'a' And *Buffer\b <= 'z'
			Result = (Result << 4) | (*Buffer\b - 'W')
		ElseIf *Buffer\b >= 'A' And *Buffer\b <= 'Z'
			Result = (Result << 4) | (*Buffer\b - '7')
		Else
			Break
		EndIf
		*Buffer + 1
	ForEver

	ProcedureReturn Result
EndProcedure

Procedure C4U_CheckForUpdateThread(Dummy.l)
	Protected *Buffer, *Byte.BYTE
	Protected ClientID.l, Size.l, Length.l, Result.l, TimeOUT.l, FileID.l = -1, OverFlow.l, P.l, A.l, B.l, C.l, Pos.l, I.l, Partial.l

	;/---------------------
	;| Main Thread
	;|
	;| No need to use Threadsafe-Option
	;| of Compiler (there aren't any strings!)
	;|
	;/---------------------

	*Buffer = AllocateMemory(#C4U_START_BUFFER)
	If *Buffer = 0
		_C4U_\LastError = #C4U_NO_MEMORY_AVAILABLE
		ProcedureReturn
	EndIf

	OverFlow = #C4U_START_BUFFER

	ClientID = C4U_Connect(_C4U_\URL, MemoryStringLength(_C4U_\URL))
	If ClientID = 0
		_C4U_\LastError = #C4U_UNABLE_TO_REACH_HOST
		ProcedureReturn
	EndIf

	Size   = 0
	Length = 0
	Result = #False
	Dim S.l(10)

	TimeOUT = ElapsedMilliseconds() + _C4U_\TimeOUT

	Repeat

		If _C4U_\Phase = 10
			;Canceled
			Break
		EndIf

		If ClientID = 0
			If _C4U_\Phase = 2
				;New URL!
				ClientID = C4U_Connect(*Buffer + S(4), S(5))
				If ClientID = 0
					_C4U_\LastError = #C4U_UNABLE_TO_REACH_HOST
					Break
				EndIf

				_C4U_\Phase + 1
				Length  = 0
				TimeOUT = ElapsedMilliseconds() + _C4U_\TimeOUT
			Else
				Delay(5)
			EndIf

		Else

			Select NetworkClientEvent(ClientID)

				Case 0
					If TimeOUT < ElapsedMilliseconds()
						_C4U_\LastError = #C4U_TIMED_OUT
						Break
					EndIf
					Delay(5)

				Case #PB_NetworkEvent_Data

					TimeOUT = ElapsedMilliseconds() + _C4U_\TimeOUT
					If Length >= OverFlow
						*Buffer = ReAllocateMemory(*Buffer, MemorySize(*Buffer) + (#C4U_READDATA_BLOCK * 2))
						If *Buffer = 0
							_C4U_\LastError = #C4U_NO_MEMORY_AVAILABLE
							Break
						EndIf
						OverFlow + (#C4U_READDATA_BLOCK * 2)
					EndIf

					If Size = -1 And Pos > 0 And Partial > 0
						P = 0
						Repeat
							I  = ReceiveNetworkData(ClientID, *Buffer + Length, Pos - Length + 10)
							If I < 0
								P = I
								Break
							EndIf
							P + I
							Length + I
							If P < Pos + 5
								Delay(5)
							Else
								Length = 0
								Break
							EndIf
						ForEver
					Else
						P = ReceiveNetworkData(ClientID, *Buffer + Length, #C4U_READDATA_BLOCK)
					EndIf

					If P > 0
						Length + P
						Select _C4U_\Phase

							Case 0
								;Search the Version-File
								S(0) = C4U_FindString(*Buffer, @"[version]", 0, Length) + 9
								If S(0) > 8
									S(1) = C4U_FindString(*Buffer, @"[/version]", S(0), Length) - S(0)
									If _C4U_\LastTimeChecked
										_C4U_\LastTimeChecked\l = Date()
									EndIf
									If ValF(PeekS(*Buffer + S(0), S(1))) <= ValF(PeekS(_C4U_\Version))
										_C4U_\Mode = 0
										Break
									EndIf

									S(2) = C4U_FindString(*Buffer, @"[link]", 0, Length) + 6
									S(3) = C4U_FindString(*Buffer, @"[/link]", S(2), Length) - S(2)
									S(4) = C4U_FindString(*Buffer, @"[updatefile]", 0, Length) + 12
									S(5) = C4U_FindString(*Buffer, @"[/updatefile]", S(4), Length) - S(4)
									S(6) = C4U_FindString(*Buffer, @"[infos]", 0, Length) + 7
									S(7) = C4U_FindString(*Buffer, @"[/infos]", S(6), Length) - S(6)
									S(8) = C4U_FindString(*Buffer, @"[sfv]", 0, Length) + 5
									S(9) = C4U_FindString(*Buffer, @"[/sfv]", S(8), Length) - S(8)
									If S(8) > 4 And S(9) > 0
										CopyMemory(*Buffer + S(8), _C4U_\SFV, S(9))
										PokeB(_C4U_\SFV + S(9), 0)
									EndIf
									If S(4) > 11 And S(5) > 0 And S(6) > 6 And S(7) > 0
										CloseNetworkConnection(ClientID)
										ClientID = 0
										Length   = 0
										If _C4U_\Mode & #C4U_MODE_USE_DIALOG
											If S(2) > -1 And S(3) > 0
												CopyMemory(*Buffer + S(2), _C4U_\Link, S(3))
												PokeB(_C4U_\Link + S(3), 0)
											EndIf
											_C4U_\P = @S()
											A = CreateThread(@C4U_OpenUpdateWindow(), *Buffer)
											If A
												Repeat
													Delay(5)
												Until _C4U_\P = 0
												_C4U_\Phase = 1
											Else
												_C4U_\Phase = 2
											EndIf
										Else
											_C4U_\Phase = 2
										EndIf
									EndIf
								Else
									P = 0
									For i = 0 To Length - 1
										If PeekB(*Buffer + i) = 32
											P = PeekL(*Buffer + i)
											Break
										EndIf
									Next i
									If P = '404 '
										;File not Found
										_C4U_\LastError = #C4U_VERSION_FILE_NOT_FOUND
										Break
									EndIf
								EndIf

							Case 3
								;First Check of HTTP
								For i = 0 To Length - 1
									If PeekB(*Buffer + i) = 32
										P = PeekL(*Buffer + i)
										Break
									EndIf
								Next i

								If P = '203 '
									;Redirect
									P = C4U_FindString(*Buffer, @"location:", 0, Length)
									If P <> -1
										Size = C4U_FindString(*Buffer, ?C4U_LineFeed, P, Length)
										If Size <> -1
											CloseNetworkConnection(ClientID)
											ClientID = C4U_Connect(*Buffer + P + 10, Size - P - 11)
											If ClientID
												Length  = 0
												TimeOUT = ElapsedMilliseconds() + _C4U_\TimeOUT
											Else
												_C4U_\LastError = #C4U_UNABLE_TO_REACH_HOST
												Break
											EndIf
										EndIf
									EndIf
								ElseIf P = '002 '
									;OK lets go
									Pos = C4U_FindString(*Buffer, ?C4U_LineEnde, 0, Length)
									If Pos <> -1
										Size = -1
										A = C4U_FindString(*Buffer, @"content-length:", 0, Length)
										If A <> -1
											Size   = 0
											C      = 1
											B      = C4U_FindString(*Buffer, ?C4U_LineFeed, A, Length)
											If B <> -1
												A + 15
												*Byte = *Buffer + B
												For i = A To B
													*Byte - 1
													If *Byte\b >= '0' And *Byte\b <= '9'
														Size + (C * (*Byte\b - '0'))
														C * 10
													EndIf
												Next i
											EndIf
											Pos + 4
										ElseIf C4U_FindString(*Buffer, @"transfer-encoding: chunked", 0, Length) <> -1
											B       = C4U_FindString(*Buffer, ?C4U_LineFeed, Pos + 4, Length) - Pos
											Partial = C4U_Hex2Dec(*Buffer + Pos + 2)
											Pos + B + 1
										Else
											_C4U_\LastError = #C4U_UNSUPPORTED_SERVER
											Break
										EndIf
										FileID = CreateFile(#PB_Any, PeekS(_C4U_\PathToSaveFileTo) + PeekS(_C4U_\FileName))
										If FileID
											If Length - Pos > 0
												If Size = -1
													;Chunks
													While Length - Pos > Partial
														WriteData(FileID, *Buffer + Pos, Partial)
														Pos + Partial
														Partial = C4U_Hex2Dec(*Buffer + Pos)
														B       = C4U_FindString(*Buffer, ?C4U_LineFeed, Pos + 2, Length)
														Pos = B + 1
														If Partial = 0
															CloseFile(FileID)
															FileID = 0
															Result = #True
															Break 2
														EndIf
													Wend
													WriteData(FileID, *Buffer + Pos, Length - Pos)
													Pos + Partial - Length
												Else
													WriteData(FileID, *Buffer + Pos, Length - Pos)
													If Length - Pos >= Size
														CloseFile(FileID)
														FileID = 0
														Result = #True
														Break
													Else
														Pos = Length - Pos
														If _C4U_\Mode & #C4U_MODE_USE_DIALOG
															_C4U_\Status = Int(Pos / Size * 100)
														EndIf
													EndIf
												EndIf
											EndIf
											_C4U_\Phase + 1
											Length = 0
										Else
											_C4U_\LastError = #C4U_UNABLE_TO_CREATE_FILE
											Break
										EndIf
									EndIf
								ElseIf P = '404 '
									;File not Found
									_C4U_\LastError = #C4U_FILE_NOT_FOUND
									Break
								EndIf
							Case 4
								If Size = -1
									If Pos > 0
										;Old things...
										WriteData(FileID, *Buffer, Pos)
										Partial = C4U_Hex2Dec(*Buffer + Pos)
										B       = C4U_FindString(*Buffer, ?C4U_LineFeed, Pos + 2, Length)
										Pos = B + 1
										If Partial = 0
											CloseFile(FileID)
											FileID = 0
											Result = #True
											Break
										EndIf
									EndIf
									While Length - Pos > Partial
										WriteData(FileID, *Buffer + Pos, Partial)
										Pos + Partial
										Partial = C4U_Hex2Dec(*Buffer + Pos)
										B       = C4U_FindString(*Buffer, ?C4U_LineFeed, Pos + 2, Length)
										Pos = B + 1
										If Partial = 0
											CloseFile(FileID)
											FileID = 0
											Result = #True
											Break 2
										EndIf
									Wend
									WriteData(FileID, *Buffer + Pos, Length - Pos)
									Pos + Partial - Length
									Length = 0
								Else
									WriteData(FileID, *Buffer, Length)
									Pos + Length
									Length = 0
									If _C4U_\Mode & #C4U_MODE_USE_DIALOG
										_C4U_\Status = Int(Pos / Size * 100)
									EndIf
									If Pos >= Size
										CloseFile(FileID)
										FileID = 0
										Result = #True
										Break
									EndIf
								EndIf

						EndSelect

					EndIf

			EndSelect
		EndIf

	ForEver

	If FileID And IsFile(FileID)
		CloseFile(FileID)
	EndIf

	If ClientID
		CloseNetworkConnection(ClientID)
	EndIf

	If Result
		If MemoryStringLength(_C4U_\SFV)
			If MD5FileFingerprint(PeekS(_C4U_\PathToSaveFileTo) + PeekS(_C4U_\FileName)) <> PeekS(_C4U_\SFV)
				;File is corrupted
				DeleteFile(PeekS(_C4U_\PathToSaveFileTo) + PeekS(_C4U_\FileName))
				_C4U_\LastError = #C4U_CORRUPTED_FILE
				Result = #False
			EndIf
		EndIf
	EndIf

	If *Buffer
		FreeMemory(*Buffer)
	EndIf

	If Result
		If _C4U_\Mode & #C4U_MODE_START_UPDATE
			RunProgram(PeekS(_C4U_\PathToSaveFileTo) + PeekS(_C4U_\FileName), "-s", PeekS(_C4U_\PathToSaveFileTo))
		EndIf
		If _C4U_\Mode & #C4U_MODE_END_IF_UPDATE
			End
		EndIf
	EndIf
	_C4U_\ThreadID = 0

EndProcedure

Procedure.l C4U_GetLastError()
	Protected Result.l

	Result          = _C4U_\LastError
	_C4U_\LastError = 0
	ProcedureReturn Result

EndProcedure

Procedure.l C4U_CheckForUpdate()

	If _C4U_\InitOK = 0
		_C4U_\LastError = #C4U_NOT_YET_INITIALIZED
		ProcedureReturn #False
	EndIf
	_C4U_\ThreadID = CreateThread(@C4U_CheckForUpdateThread(), 0)
	If _C4U_\ThreadID = 0
		_C4U_\LastError = #C4U_UNABLE_TO_START_THREAD
		ProcedureReturn #False
	EndIf
	ProcedureReturn #True

EndProcedure

Procedure.l C4U_Init(OwnVersion.s, CheckURL.s, PathToSaveFileTo.s, TimeOUT.l, Mode.l = 0, *LastTimeChecked = 0, MainWindowID.l = 0)
	Protected Size.l
	;/--------------------
	;| PARAMETERS (in Order of appearance):
	;|
	;| OwnVersion             = String, that contains your applications Version (as "String-Float")
	;|                          Example : "1.000"
	;| CheckURL               = String, that contains the URL to the version-file
	;|                          Example : "http://h3x0r.ath.cx/check/patchmaster.php"
	;| PathToSaveFileTo       = Path where a possibly available Updatefile will be saved to
	;|                          Example : "C:\WINDOWS\"
	;| TimeOUT                = TimeOUT in ms
	;|                          Example : 3000
	;|
	;|             [OPTIONAL-PARAMETERS]
	;| Mode                   = Combination of the following Flags:
	;|                          #C4U_MODE_USE_DIALOG :
	;|                                   Open a Window when update is available To give
	;|                                   User ability to choose if he wants to update
	;|                                   or not.
	;|                                   If this Bit is not set, the Update will be downloaded silently
	;|                          #C4U_MODE_END_IF_UPDATE :
	;|                                   Ends the application, If update is available
	;|                          #C4U_MODE_START_UPDATE :
	;|                                   Trys To run the Update after End
	;|                          #C4U_MODE_START_IMMEDIATELY :
	;|                                   Starts directly after this Init
	;|                                   ( No need to call C4U_CheckForUpdate() )
	;| *LastTimeChecked       = Address of a (LONG)-Variable, which will be set to Date()
	;|                          when checking was successfull (only CHECKING, NOT DOWNLOADING!).
	;|                          (useful when you only want to check any 24h or whenever)
	;| MainWindowID           = WindowID (Api-Handle) of Main-Window
	;| ReturnValue            = #False , when something went wrong
	;|                          #True , when Thread has been started
	;/---------------------

	If OwnVersion = "" Or CheckURL = "" Or PathToSaveFileTo = ""
		_C4U_\LastError = #C4U_PARAMETERS_FORGOTTEN
		ProcedureReturn #False
	EndIf

	Size = Len(OwnVersion) + Len(CheckURL) + Len(PathToSaveFileTo) + 4

	If _C4U_\Version
		FreeMemory(_C4U_\Version)
	EndIf

	_C4U_\Version = AllocateMemory(Size + #MAX_PATH + 2048)
	If _C4U_\Version = 0
		_C4U_\LastError = #C4U_NO_MEMORY_AVAILABLE
		ProcedureReturn #False
	EndIf

	_C4U_\URL              = _C4U_\Version + Len(OwnVersion) + 1
	_C4U_\PathToSaveFileTo = _C4U_\URL + Len(CheckURL) + 1
	_C4U_\SFV              = _C4U_\PathToSaveFileTo + Len(PathToSaveFileTo) + 1
	_C4U_\FileName         = _C4U_\SFV + 33
	_C4U_\Link             = _C4U_\FileName + #MAX_PATH + 1

	PokeS(_C4U_\Version, OwnVersion)
	PokeS(_C4U_\URL, CheckURL)
	PokeS(_C4U_\PathToSaveFileTo, PathToSaveFileTo)
	PokeB(_C4U_\SFV, 0)

	_C4U_\TimeOUT         = TimeOUT
	_C4U_\LastTimeChecked = *LastTimeChecked
	_C4U_\MainWindowID    = MainWindowID
	_C4U_\Mode            = Mode
	_C4U_\Phase           = 0
	_C4U_\InitOK          = #True
	If Mode & #C4U_MODE_START_IMMEDIATELY
		C4U_CheckForUpdate()
	EndIf

	ProcedureReturn #True

EndProcedure

DataSection
	C4U_GET_REQUEST_1:
	Data.s "GET "
	C4U_GET_REQUEST_2:
	Data.s " HTTP/1.1" + #CRLF$ + "Host: "
	C4U_GET_REQUEST_3:
	Data.s #CRLF$ + "User-Agent: Mozilla/5.0" + #CRLF$ + "Accept: */*" + #CRLF$ + #CRLF$
	C4U_LineFeed:
	Data.s #LF$
	C4U_LineEnde:
	Data.s #CRLF$ + #CRLF$
EndDataSection
Hier noch ein Beispiel (nicht zu oft testen, das geht auf meinen Traffic ;)

Code: Alles auswählen

XIncludeFile "Check4Updates.pbi"

InitNetwork()

If OpenWindow(0, 0, 0, 600, 300, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
	EditorGadget(0, 10, 10, 580, 280)
	AddGadgetItem(0, -1, "This is a little demonstration")
	AddGadgetItem(0, -1, "Of the Check4Updates.pbi - Include.")
	AddGadgetItem(0, -1, "")
	AddGadgetItem(0, -1, "Have Fun")
	AddGadgetItem(0, -1, "HeX")

	Dim ErrorMessages.s(11)
	ErrorMessages(#C4U_NO_ERROR)               = "No Error"
	ErrorMessages(#C4U_UNABLE_TO_START_THREAD) = "Error when trying to create a thread."
	ErrorMessages(#C4U_NO_MEMORY_AVAILABLE)    = "Unable to allocate memory."
	ErrorMessages(#C4U_NOT_YET_INITIALIZED)    = "Not yet initialized!"
	ErrorMessages(#C4U_PARAMETERS_FORGOTTEN)   = "You have forgotten necessarily parameters!"
	ErrorMessages(#C4U_TIMED_OUT)              = "Connection Timed Out!"
	ErrorMessages(#C4U_UNABLE_TO_REACH_HOST)   = "Unable to Reach Host!"
	ErrorMessages(#C4U_UNABLE_TO_CREATE_FILE)  = "Unable to Create File!"
	ErrorMessages(#C4U_CORRUPTED_FILE)         = "Corrupted File received!"
	ErrorMessages(#C4U_VERSION_FILE_NOT_FOUND) = "Version-File not found on Server!"
	ErrorMessages(#C4U_FILE_NOT_FOUND)         = "File not found on Server!"
	ErrorMessages(#C4U_UNSUPPORTED_SERVER)     = "This Server isn't compatible with the Script!"

	If C4U_Init("3.60", "http://h3x0r.ath.cx/Sonstiges/WinRar.txt", "C:\", 3000, #C4U_MODE_USE_DIALOG | #C4U_MODE_START_IMMEDIATELY, @Last_Time_Checked, WindowID(0)) = #False
		MessageRequester("Error!", ErrorMessages(C4U_GetLastError()))
	EndIf

	Repeat
		Select WaitWindowEvent(500)
			Case 0
				Error = C4U_GetLastError()
				If Error
					AddGadgetItem(0, -1, "Error: " + ErrorMessages(Error))
				EndIf
			Case #PB_Event_CloseWindow
				If EventWindow() = 0
					Break
				EndIf
		EndSelect
	ForEver
	If Last_Time_Checked
		Debug FormatDate("Last Update: %hh:%ii:%ss", Last_Time_Checked)
	EndIf
EndIf

End
Ich glaube nicht, dass es mit sämtlich möglichen Servern klarkommen wird, deswegen wäre es gut, wenn ein paar Erfahrungsberichte kommen.
(Z.B. weiss ich nicht, wie sich ein Server meldet, wenn er keine Filesize mitschickt und ob die Routine dann richtig arbeitet. Im übrigen bestücke ich dann den Progressbalken mit Zufallswerten, nur um zu zeigen, dass sich noch was tut)

Viel Spass
HeX

[Edit]
Muss wohl voll gewesen sein, da war ne Prozedur auskommentiert :freak:

[Edit2 / 2008]
Habe mal die letzte gefundene Version hochgeladen.
Zuletzt geändert von HeX0R am 13.02.2008 21:33, 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 »

:allright:
Interessanter Code, aber noch nicht genauer getestet sondern nur erstmal
Deinen Traffik belastet :mrgreen:

Werde es mir aber noch genauer ansehen und testen!

// Nachtrag:
Habs jetzt mal auf meinem Webspace getestet, keine Probleme.
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
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

Bekomme eine Fehlermeldung: Keine Funktion
Wird eine Lib benutzt.
Version: beta9

Zeile 177: A = ME_FindString(INFO\URL, @"/", 0)
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Die Prozedur war versehentlich nach einer winzigen Veränderung auskommentiert.
(Das hätte man auch fast sehen können ;) )
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:(Das hätte man auch fast sehen können ;) )
Bei manchen ist es so, Stecker rein, Schalter an, Geht nicht: Muääähh
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
Antworten