Ich bin mir bewusst, meine Fragen sind etwas skurril und befassen sich mit recht altem Code zum Teile.
Da ich gerade auch da meistens das passende gefunden hatte.
Und so verhält es sich leider auch dieses Mal wieder.
Es geht im Wesentlichen um einen Patcher Code.
Da ist es so, dass der bestehende Code, folgt am Ende, aus zwei Prozeduren besteht.
Einmal Patch erstellen, einmal Patch gebrauchen.
Nun, der Knackpunkt, das Verzeichnis, Source resp. Target Files und Patch Destination sind in der Procedure nicht fix.
Wenn ich jetzt eine GUI für mich erstelle, da ich mit Konsolen Programmierung zu wenig Erfahrung habe, muss ich diese
drei Werte herleiten. (GUI = OK)
Aber ich bin natürlich die ganze Zeit am Suchen und verstehen wie ich denn diese Procedure jetzt ansprechen soll.
Ich stehe wieder mal auf dem Schlauch, wahrlich habe ich mich wohl auch komplett ins AUS manövriert, das mag auch sein.
Ich habe das Ganze in zwei Dateien, der Procedure sowie meinem GUI. (Danke an Axolotl der mir immer wieder mal auf den Hinterkopf schlägt.)
Er hatte mir etwas geholfen mit der GUI.
Aber auch Euch allen, welche mir immer wieder mit neuen Erkenntnissen beflügelt weiter zu machen an meinem kleinen Projekt, das
leider sich ausgeweitet hatte.
Sorry, ich schweife ab.......
Frage: Wie kann ich diese Procedure ansprechen, nachdem ich die Verzeichnisse ausgewählt habe?
Vielen lieben Dank und Euch allen ein ganz schönes Wochenende
Grüsse aus Bern
Christian
PS: Die beiden einzigen Teile an welchen ich bis jetzt Hand angelegt hatte, waren die GUI sowie create-patch.
[/UPDATE: gesamter Source vorhanden auf pcloud mit Link. [\UPDATE]
Patch Maker Source
GUI:
Code: Alles auswählen
;- Top
; -----------------------------------------------------------------------------
; Name:
; Description:
; Author:
; Date: 2024-08-22
; Version:
; PB-Version:
; OS:
; Credit:
; Forum:
; Created by: IceDesign
; -----------------------------------------------------------------------------
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
;- Enumerations
Enumeration Window
#Window_0
EndEnumeration
Enumeration Gadgets
#Btn_Execute
#Btn_Path_1
#Btn_Path_2
#Str_Path_1
#Str_Path_2
#Str_Path_3
EndEnumeration
;- Global
Global InitialPath1$
Global Path1$
Global InitialPath2$
Global Path2$
Global InitialPath3$
Global Path3$
;- Declare
Declare Resize_Window_0()
Declare Open_Window_0(X = 0, Y = 0, Width = 540, Height = 400)
;- Procedure Main Window
Procedure Resize_Window_0()
Protected Window_0_WidthIni = 540, Window_0_HeightIni = 400
Protected ScaleX.f, ScaleY.f
ScaleX = WindowWidth(#Window_0) / Window_0_WidthIni : ScaleY = WindowHeight(#Window_0) / Window_0_HeightIni
ResizeGadget(#Btn_Path_1, ScaleX * 40, ScaleY * 270, ScaleX * 100, ScaleY * 45)
ResizeGadget(#Btn_Path_2, ScaleX * 170, ScaleY * 270, ScaleX * 100, ScaleY * 45)
ResizeGadget(#Btn_Execute, ScaleX * 320, ScaleY * 270, ScaleX * 130, ScaleY * 45)
EndProcedure
;- Procedure Open Main Window
Procedure Open_Window_0(X = 0, Y = 0, Width = 540, Height = 400)
If OpenWindow(#Window_0, X, Y, Width, Height, "Title", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
ButtonGadget(#Btn_Path_1, 40, 270, 100, 45, "Path 1")
ButtonGadget(#Btn_Path_2, 170, 270, 100, 45, "Path 2")
DisableGadget(#Btn_Path_2, #True)
ButtonGadget(#Btn_Execute, 320, 270, 130, 45, "Execute")
DisableGadget(#Btn_Execute, #True)
StringGadget(#Str_Path_1, 8, 80, 306, 20, Path1$, #PB_String_ReadOnly) ;Path$
StringGadget(#Str_Path_2, 8, 100, 306, 20, Path2$, #PB_String_ReadOnly) ;Path$
StringGadget(#Str_Path_3, 8, 120, 306, 20, Path3$, #PB_String_ReadOnly) ;Path$
BindEvent(#PB_Event_SizeWindow, @Resize_Window_0(), #Window_0)
PostEvent(#PB_Event_SizeWindow, #Window_0, 0)
ProcedureReturn #True
EndIf
EndProcedure
; XIncludeFile "createpatch.pbi"
CompilerIf #PB_Compiler_IsMainFile
;- Main Program
If Open_Window_0()
;- Event Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
;-> Event Gadget
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn_Path_1 ; Path 1
InitialPath1$ = "C:\Users\cschaer\Documents\my Basic\PureBasic" ; anfänglichen Pfad für die Anzeige festlegen (kann auch leer sein)
Path1$ = PathRequester("Bitte wählen Sie einen Pfad aus", InitialPath1$)
If Path1$
SetGadgetText(#Str_Path_1, Path1$)
DisableGadget(#Btn_Path_1, #True) ;<-- disable ???
DisableGadget(#Btn_Path_2, #False) ;<--
Else
MessageRequester("Information", "Der Requester wurde abgebrochen.", 0)
EndIf
Case #Btn_Path_2 ; Path 2
InitialPath2$ = "C:\Users\cschaer\Documents\my Basic\PureBasic" ; anfänglichen Pfad für die Anzeige festlegen (kann auch leer sein)
Path2$ = PathRequester("Bitte wählen Sie einen Pfad aus", InitialPath2$)
If Path2$
SetGadgetText(#Str_Path_2, Path2$)
DisableGadget(#Btn_Path_2, #True)
DisableGadget(#Btn_Execute, #False)
Else
MessageRequester("Information", "Der Requester wurde abgebrochen.", 0)
EndIf
Case #Btn_Execute ; Execute
InitialPath3$ = "C:\Users\cschaer\Documents\my Basic\PureBasic\my Patch\new" ; anfänglichen Pfad für die Anzeige festlegen (kann auch leer sein)
Path3$ = PathRequester("Bitte wählen Sie einen Pfad aus", InitialPath3$)
If Path3$
SetGadgetText(#Str_Path_3, Path3$)
DisableGadget(#Btn_Execute, #True) ;<--
Else
MessageRequester("Information", "Der Requester wurde abgebrochen.", 0)
EndIf
EndSelect
EndSelect
ForEver
EndIf
CompilerEndIf
Code: Alles auswählen
;createpatch(file1.s,file2.s,patchpath.s)
;file1 = Pfad zur alten Version einer Datei
;file2 = Pfad zur neuen Version einer Datei
;Patchpath = Speicherpfad des Patches
Procedure createpatch(Path1$,Path2$,Path3$)
Protected MemPoint.l = 0 , LenOfFile1.l , LenOfFile2.l
Protected ByteOld.b , ByteNew.b
Protected *Data1, *Data2, *Data3
UseMD5Fingerprint()
;Wenn file1 = file2, Prozedure verlassen
If FileFingerprint(Path1$, #PB_Cipher_MD5) = FileFingerprint(Path2$,#PB_Cipher_MD5)
ProcedureReturn #False
EndIf
ReadFile(0,Path1$)
ReadFile(1,Path2$)
LenOfFile1 = Lof(0)
LenOfFile2 = Lof(1)
*Data1 = AllocateMemory(LenOfFile1)
*Data2 = AllocateMemory(LenOfFile2)
*Data3 = AllocateMemory(LenOfFile2+33) ; '+33' für den MD5 Header
ReadData(0,*Data1,LenOfFile1)
ReadData(1,*Data2,LenOfFile2)
PokeS(*Data3,FileFingerprint(Path1$,#PB_Cipher_MD5)) ; Speichert MD5Fingerprint
While MemPoint < LenOfFile2
If MemPoint < LenOfFile1
ByteOld = PeekB(*Data1+MemPoint)
Else
ByteOld = 0
EndIf
ByteNew = PeekB(*Data2+MemPoint)
If ByteOld = ByteNew
PokeB(*Data3+33+MemPoint,0) ;ja nicht den MD5 Header überschreiben
Else
PokeB(*Data3+33+MemPoint,ByteOld-ByteNew)
EndIf
MemPoint = MemPoint + 1
Wend
CreatePack(0,Path3$ ,9)
AddPackMemory(0,*Data3,LenOfFile2+33,Path2$)
ClosePack(0)
CloseFile(0) ;keine Ahnung wann man am besten file1 u. file2 closed
CloseFile(1)
FreeMemory(*Data1)
FreeMemory(*Data2)
FreeMemory(*Data3)
ProcedureReturn #True
EndProcedure
Code: Alles auswählen
;patchit(file1.s,pak.s)
;file1 = Pfad zur alten Version einer Datei
;pak = Pfad zum Patch
Procedure patchit(file1.s,pak.s)
Protected ByteOld.b , ByteDiff.b
Protected PakMD5.s
Protected PakSize.l, i.l
Protected *Patch, *DataFile
OpenPack(0,pak)
*Patch = NextPackEntry(0)
PakSize = PackEntrySize(0)
PakMD5 = PeekS(*Patch,32)
If FileFingerprint(file1, #PB_Cipher_MD5) <> PakMD5 ;MD5 überprüfen
ProcedureReturn #False
EndIf
CopyFile(file1,file1+".backup") ;Backup erstellen
OpenFile(0,file1)
For i = 33 To PakSize ;Nachdem MD5Header weiterlesen
FileSeek(0,i-33)
ByteOld = ReadByte(0)
ByteDiff = PeekB(*Patch+i)
FileSeek(0,i-33)
WriteByte(0,ByteOld-ByteDiff)
Next i
If (PakSize-33) < Lof(0) ;Wenn Original-Datei > Update Datei, dann....
FileSeek(0,0)
*DataFile = AllocateMemory(PakSize-33)
ReadData(0,*DataFile,PakSize-33)
CloseFile(0)
DeleteFile(file1)
CreateFile(0,file1)
WriteData(0,*DataFile,PakSize-33)
EndIf
CloseFile(0)
ClosePack(0)
FreeMemory(*Patch)
FreeMemory(*DataFile)
ProcedureReturn #True
EndProcedure