Afin de limiter le débit réseau / charge cpu
+ Auto Reprise où la copie en était si elle est stoppée.
Code : Tout sélectionner
; Droopy 07/05/05
; PureBasic 3.93
ProcedureDLL GetDiskFreeSpaceEx(Drive.s) ; Included in Droopy's Lib
; GetDiskFreeSpaceEx() Author = Freak
Structure union
LowPart.l
HighPart.l
EndStructure
lpFreeBytesAvailable.union
lpTotalNumberOfBytes.union
lpTotalNumberOfFreeBytes.union
GetDiskFreeSpaceEx_(@Drive,@lpFreeBytesAvailable,@lpTotalNumberOfBytes,@lpTotalNumberOfFreeBytes)
; LowPart contient 32 Bits
; On décale à droite de 20 bits ( il reste 12 bits significatifs )
; Attention le décalage recopie le bit de signe !
; 20 bits --> /1024/1024 --> Résultat en Mo !!!
lpTotalNumberOfFreeBytes\LowPart>>20
; On nettoie le bit de signe recopié avec un masque ( de 12 bits bien sur )
lpTotalNumberOfFreeBytes\LowPart & $FFF
; On décale HighPart de 12 à gauche
lpTotalNumberOfFreeBytes\HighPart <<12
; Et on fusionne le tout avec un OU
; La taille est en Mo
ProcedureReturn lpTotalNumberOfFreeBytes\LowPart | lpTotalNumberOfFreeBytes\HighPart
EndProcedure
ProcedureDLL Timer(ProcedurePointer) ; Included in Droopy's Lib
Static FlagTimer
; Create the LinkedList the first time !
If FlagTimer=0
NewList IdThreads() ; Store the ThreadId
FlagTimer=1
EndIf
AddElement(IdThreads())
LastElement(IdThreads())
IdThreads()=CreateThread(ProcedurePointer,0)
ProcedureReturn ListIndex(IdThreads())
EndProcedure
ProcedureDLL TimerKill(Id) ; Included in Droopy's Lib
SelectElement(IdThreads(),Id)
KillThread(IdThreads())
EndProcedure
;/ BackgroundTransfertInit(SourceFile.s,DestinationFile.s,PacketSize,Frequency)
; Initialise the Lib
; Return 1 if SourceFile Exist / Enought free space avalaible @ Target Destination
;/ BackgroundTransfertState()
; Return 0 if transfert not finished ; 1 when finished
;/ BackGroundTransfertStart()
; Start the Background Transfert
;/ BackGroundTransfertStop()
; Stop the Background Transfert
;/ BackGroundTransfertPercentage()
; Get the transfert state in percentage
;/ BackGroundTransfertVerify()
; When transfert finished, this function test if source = destination : 1 = true
Global BGTSource.s,BGTDestination.s,BGTTaillePaquets,BGTTempo,BGTFlag,BGTTimerId,BGTTailleDestination,BGTTailleSource
ProcedureDLL BackGroundTransfertStop()
TimerKill(BGTTimerId)
EndProcedure
ProcedureDLL BackgroundTransfertInit(SourceFile.s,DestinationFile.s,PacketSize,Frequency)
BGTSource=SourceFile
BGTDestination=DestinationFile
BGTTaillePaquets=PacketSize
BGTTempo=Frequency
BGTFlag=0
retour=1
If FileSize(BGTSource)=-1
retour=0 ; File does not exist
Else
; Source file exist
; Test if there is enought space for file copy
ResteACopier=FileSize(BGTSource)
If FileSize(BGTDestination)>0 : ResteACopier-FileSize(BGTDestination):EndIf
ResteACopier/1024/1024
Drive.s=Left(BGTDestination,2)
SpaceNeeded=GetDiskFreeSpaceEx(Drive)
SpaceNeeded-ResteACopier
If SpaceNeeded<=0 : retour=0 : EndIf
EndIf
ProcedureReturn retour
EndProcedure
ProcedureDLL BackgroundTransfertState()
ProcedureReturn BGTFlag
EndProcedure
Procedure BackgroundTransfertOnePacket()
OpenFile(0,BGTSource)
BGTTailleSource=Lof()
OpenFile(1,BGTDestination.s)
BGTTailleDestination=Lof()
DebutCopie=BGTTailleDestination
If DebutCopie=BGTTailleSource
BGTFlag=1 ; On a déjà tout copié on quitte
CloseFile(1)
CloseFile(0)
BackGroundTransfertStop() ; Kill thread when finished
Else
FinCopie=DebutCopie+BGTTaillePaquets
If FinCopie>BGTTailleSource : FinCopie=BGTTailleSource : EndIf
OctetsALire=FinCopie-DebutCopie
*Tampon=AllocateMemory(OctetsALire)
UseFile(0)
FileSeek(DebutCopie)
ReadData(*Tampon,OctetsALire)
UseFile(1)
FileSeek(Lof())
WriteData(*Tampon,OctetsALire)
CloseFile(1)
CloseFile(0)
EndIf
ProcedureReturn BGTFlag
EndProcedure
Procedure BackGroundTransfertTimer() ; Transfert en boucle des paquets = Timer
Repeat
Delay(BGTTempo)
BackgroundTransfertOnePacket()
ForEver
EndProcedure
ProcedureDLL BackGroundTransfertStart() ; Lance le transfert ( Lance le Timer )
BGTTimerId=Timer(@BackGroundTransfertTimer())
EndProcedure
ProcedureDLL BackGroundTransfertPercentage()
retour.f=(BGTTailleDestination/BGTTailleSource)*100
If BGTFlag=1 : retour=100 : EndIf
ProcedureReturn retour
EndProcedure
Procedure BackGroundTransfertVerify()
If MD5FileFingerprint(BGTSource) = MD5FileFingerprint(BGTDestination) : retour=1 : EndIf
ProcedureReturn retour
EndProcedure
;/ Test the Lib
; DeleteFile("c:\copie.msi") ; Restart the copy
retour=BackgroundTransfertInit("c:\Test.msi","c:\Copie.msi",16192,1)
If retour=0 : Beep_(400,500):End:EndIf
BackGroundTransfertStart()
OpenWindow(0,0,0,320,160,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Background Transfert") And CreateGadgetList(WindowID(0))
TextGadget (0, 10, 10,250, 20, "0 %",#PB_Text_Center)
ProgressBarGadget(1, 10, 30,250, 30, 0,100,#PB_ProgressBar_Smooth )
Repeat
Delay(10)
SetGadgetState (1, BackGroundTransfertPercentage()) ; set 1st progressbar (ID = 0) to 50 of 100
SetGadgetText(0,Str(BackGroundTransfertPercentage())+"%")
Until WindowEvent()=#PB_Event_CloseWindow Or BackgroundTransfertState()
BackGroundTransfertStop()
If BackGroundTransfertVerify()
MessageRequester("Background Transfert","Success")
Else
MessageRequester("Background Transfert","Fail")
EndIf