How to shows the progress of extracting files with ProgressBar ?
Posted: Sat Jun 01, 2024 10:52 am
I am new to PB.
My primary language is not US/UK. I am using Google Translate.
I have completed the exercise to Extract a file with 7Zip Standalone: https://www.7-zip.org/a/7z2406-extra.7z
But I am having trouble knowing where to start, as I need to display the extraction process in a Progress Bar.
Here, I can use "e" switch, I tried it but it causes an additional problem of "unable to extract file" if a folder exists with the same name as this file.
Please help.
Thanks.
Here is the code.
My primary language is not US/UK. I am using Google Translate.
I have completed the exercise to Extract a file with 7Zip Standalone: https://www.7-zip.org/a/7z2406-extra.7z
But I am having trouble knowing where to start, as I need to display the extraction process in a Progress Bar.
Here, I can use "e" switch, I tried it but it causes an additional problem of "unable to extract file" if a folder exists with the same name as this file.
Please help.
Thanks.
Here is the code.
Code: Select all
CompilerIf #PB_Compiler_Thread = 0
CompilerWarning "Enable thread safe option!"
CompilerEndIf
EnableExplicit
Enumeration Window
#mainWindow
EndEnumeration
Enumeration #PB_Event_FirstCustomValue
#MyEvent_7zip_Start
#MyEvent_7zip_Doing
#MyEvent_7zip_Finished
#MyEvent_7zip_Validate
EndEnumeration
Enumeration Gadgets
#Btn_Extract
#Txt_Clock
#Edit_1
#StatusBar_1
#Txt_1
EndEnumeration
Structure udtThreadControl
ThreadID.i
Window.i
Event.i
EndStructure
Structure SEVEN7ZIP Extends udtThreadControl
Init.i
SevenFile.s
ExitCode.i
Output.s
VersionS.s
VersionI.i
Password.s
Flags.i
;
nFiles.i
FileList.s
nFolders.i
FolderList.s
;
inFile.s
outFolder.s
EndStructure
Global *thr7zip.SEVEN7ZIP = AllocateStructure(SEVEN7ZIP)
Global BayZip$ = GetTemporaryDirectory() + "s7zip.exe"
Procedure Set7ZipPassword(mk$)
With *thr7zip
\Password = mk$
EndWith
EndProcedure
Procedure Set7ZipFlags(Flags.i)
With *thr7zip
\Flags = Flags
EndWith
EndProcedure
Procedure Load7zip()
Define iFileNr.i, iResult.i
DeleteFile(BayZip$, #PB_FileSystem_Force)
iFileNr = CreateFile(#PB_Any, BayZip$)
If iFileNr
iResult = WriteData(iFileNr, ?file_7zip, ?file_7zip_end - ?file_7zip)
Debug "Bytes: " + iResult
CloseFile(iFileNr)
Delay(500)
EndIf
EndProcedure
Procedure.i __7Zip_Run(exx.s, Parameter.s = "", Directory.s = "")
Protected PID.i = #Null
With *thr7zip
\ExitCode = 0
\Output = ""
PID = RunProgram(exx, Parameter, Directory, #PB_Program_Hide | #PB_Program_Open | #PB_Program_Read)
If (PID)
While (ProgramRunning(PID))
While (AvailableProgramOutput(PID))
\Output + ReadProgramString(PID, #PB_UTF8) + #LF$ ; Phải là #PB_UTF8
Wend
Delay(1)
Wend
\ExitCode = ProgramExitCode(PID)
CloseProgram(PID)
EndIf
EndWith
ProcedureReturn (Bool(PID))
EndProcedure
Procedure Reset7Zip()
With *thr7zip
\Password = ""
\Flags = #Null
EndWith
EndProcedure
Procedure.s Get7ZipVersion()
With *thr7zip
If (\Init)
ProcedureReturn (\VersionS)
Else
ProcedureReturn ("")
EndIf
EndWith
EndProcedure
Procedure.i Get7ZipBuildNumber()
With *thr7zip
If (\Init)
ProcedureReturn (\VersionI)
Else
ProcedureReturn (0)
EndIf
EndWith
EndProcedure
Procedure.i Examine7ZipFiles(Archive$)
Protected Result.i = 0
With *thr7zip
If (\Init)
If (FileSize(Archive$) >= 0)
Protected Param$ = "l"
Param$ + " " + #DQUOTE$ + Archive$ + #DQUOTE$
If (\Password)
Param$ + " -p" + \Password
EndIf
If (__7Zip_Run(\SevenFile, Param$, GetPathPart(Archive$)))
If (\ExitCode = 0)
Protected Lines.i = 1 + CountString(\Output, #LF$)
\nFiles = 0
\FileList = ""
\nFolders = 0
\FolderList = ""
Protected i.i
Protected InList.i = #False
Protected NameOffset.i
For i = 1 To Lines
Protected Line.s = StringField(\Output, i, #LF$)
If (InList)
If (Left(Line, 19) = "-------------------")
Break
Else
If (Mid(Line, 21, 1) = "D")
\FolderList + #LF$ + Mid(Line, NameOffset)
\nFolders + 1
Else
\FileList + #LF$ + Mid(Line, NameOffset)
\nFiles + 1
EndIf
EndIf
Else
If Right(Line, 6) = " Name"
NameOffset = Len(Line) - 4 + 1
ElseIf (Left(Line, 19) = "-------------------")
InList = #True
EndIf
EndIf
Next i
\FileList = Mid(\FileList, 2)
\FolderList = Mid(\FolderList, 2)
Result = #True
EndIf
EndIf
EndIf
EndIf
EndWith
ProcedureReturn (Result)
EndProcedure
Procedure.i Get7ZipFileCount()
ProcedureReturn (*thr7zip\nFiles)
EndProcedure
Procedure.s Get7ZipFileList()
ProcedureReturn (*thr7zip\FileList)
EndProcedure
Procedure AllocateString(String.s) ; Result = Pointer
Protected *mem.string = AllocateStructure(String)
If *mem
*mem\s = String
EndIf
ProcedureReturn *mem
EndProcedure
Procedure.s FreeString(*mem.string) ; Result String
Protected r1.s
If *mem
r1 = *mem\s
FreeStructure(*mem)
EndIf
ProcedureReturn r1
EndProcedure
Procedure StartThread(*Data.udtThreadControl, *Procedure)
If Not IsThread(*Data\ThreadID)
*Data\ThreadID = CreateThread(*Procedure, *Data)
EndIf
ProcedureReturn *Data\ThreadID
EndProcedure
Procedure FreeThread(*Data.udtThreadControl, Wait = 1000)
If IsThread(*Data\ThreadID)
If WaitThread(*Data\ThreadID, Wait) = 0
KillThread(*Data\ThreadID)
EndIf
EndIf
FreeStructure(*Data)
EndProcedure
Procedure.i Extract7ZipFile(Archive$, Dest$ = "")
Protected.i Result = #False
With *thr7zip
If (\Init)
If FileSize(Archive$) > 0
If Len(Dest$) < 3
Dest$ = GetCurrentDirectory() + "temp"
EndIf
Protected Param$ = "x -y -aoa"
Param$ + " " + #DQUOTE$ + Archive$ + #DQUOTE$
Param$ + " -o" + #DQUOTE$ + Dest$ + #DQUOTE$
If (\Password)
Param$ + " -p" + #DQUOTE$ + \Password + #DQUOTE$
EndIf
If (__7Zip_Run(\SevenFile, Param$, GetPathPart(Archive$)))
If (\ExitCode = 0)
Result = #True
EndIf
EndIf
EndIf
EndIf
EndWith
ProcedureReturn (Result)
EndProcedure
Procedure.i Init7Zip(exx.s = "")
With *thr7zip
If (Not \Init)
If (exx = "")
exx = BayZip$
EndIf
If (__7Zip_Run(exx))
Protected ii.i = FindString(\Output, "7-Zip (a) ", 1, #PB_String_NoCase)
If (ii)
\SevenFile = BayZip$
\VersionS = StringField(Trim(Mid(\Output, ii + 10)), 1, " ")
\VersionI = Round(100.0 * ValF(\VersionS), #PB_Round_Nearest)
Reset7Zip()
\Init = #True
Debug "VersionS: " + \VersionS
Debug "VersionI: " + \VersionI
EndIf
EndIf
EndIf
ProcedureReturn (\Init)
EndWith
EndProcedure
Procedure Thread7Zip(*Data.SEVEN7ZIP)
Protected sdata$, doc_7zip_fullpath$, fullpath_to_extract$, mk$
With *Data
doc_7zip_fullpath$ = \inFile
fullpath_to_extract$ = \outFolder
mk$ = \Password
If FileSize(doc_7zip_fullpath$) = -1
sdata$ = "Không tìm thấy Tài nguyên."
PostEvent(#MyEvent_7zip_Finished, #mainWindow, 0, 0, AllocateString(sdata$))
EndIf
If FileSize(doc_7zip_fullpath$) > 0
Load7zip()
If (Init7Zip())
Protected FileList$, zFile$
Protected.i i, n
Set7ZipPassword(mk$)
If (Examine7ZipFiles(doc_7zip_fullpath$))
n = Get7ZipFileCount()
FileList$ = Get7ZipFileList()
For i = 1 To n
zFile$ = StringField(FileList$, i, #LF$)
If FileSize(RTrim(fullpath_to_extract$, "\") + "\" + zFile$) >= 0
sdata$ = "Xóa tập tin: " + zFile$
PostEvent(#MyEvent_7zip_Doing, #mainWindow, 0, 0, AllocateString(sdata$))
;MessageRequester("file", RTrim(fullpath_to_extract$, "\") + "\" + zFile$)
DeleteFile(RTrim(fullpath_to_extract$, "\") + "\" + zFile$, #PB_FileSystem_Force)
EndIf
If FileSize(RTrim(fullpath_to_extract$, "\") + "\" + zFile$) = -2
sdata$ = "Xóa thư mục: " + zFile$
PostEvent(#MyEvent_7zip_Doing, #mainWindow, 0, 0, AllocateString(sdata$))
;MessageRequester("thư mục", RTrim(fullpath_to_extract$, "\") + "\" + zFile$)
DeleteDirectory(RTrim(fullpath_to_extract$, "\") + "\" + zFile$, "", #PB_FileSystem_Force | #PB_FileSystem_Recursive)
EndIf
Next i
sdata$ = "Trích xuất Tài nguyên..."
PostEvent(#MyEvent_7zip_Start, #mainWindow, 0, 0, AllocateString(sdata$))
If Extract7ZipFile(doc_7zip_fullpath$, fullpath_to_extract$)
sdata$ = "Trích xuất Tài nguyên thành công."
PostEvent(#MyEvent_7zip_Finished, #mainWindow, 0, 0, AllocateString(sdata$))
EndIf
Else
sdata$ = "Sai mật khẩu."
PostEvent(#MyEvent_7zip_Finished, #mainWindow, 0, 0, AllocateString(sdata$))
EndIf
Else
sdata$ = "Không thể khởi tạo Bộ giải nén."
PostEvent(#MyEvent_7zip_Start, #mainWindow, 0, 0, AllocateString(sdata$))
EndIf
Reset7Zip()
RunProgram("taskkill", "/F /IM " + #DQUOTE$ + \SevenFile + #DQUOTE$, "", #PB_Program_Wait| #PB_Program_Hide)
DeleteFile(\SevenFile, #PB_FileSystem_Force)
EndIf
EndWith
EndProcedure
Procedure DoExtract(*dt.SEVEN7ZIP, doc_7zip_fullpath$, fullpath_to_extract$, pw$)
If Not IsThread(*dt\ThreadID)
With *dt
\inFile = doc_7zip_fullpath$
\outFolder = fullpath_to_extract$
\Password = pw$
StartThread(*dt, @Thread7Zip())
EndWith
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Declare.i update_clock(ii)
Procedure.i update_clock(ii)
Repeat
SetGadgetText(#Txt_Clock, FormatDate("%hh:%ii:%ss", Date()))
Delay(500)
ForEver
EndProcedure
Procedure StatusBar_mainWindow()
CreateStatusBar(#StatusBar_1, WindowID(#mainWindow))
AddStatusBarField(70)
AddStatusBarField(430)
StatusBarText(#StatusBar_1, 0, "Progress: ", #PB_StatusBar_BorderLess)
StatusBarProgress(#StatusBar_1, 1, 3)
EndProcedure
Procedure Resize_mainWindow()
Protected mainWindow_WidthIni = 500, mainWindow_HeightIni = 180
Protected ScaleX.f, ScaleY.f
ScaleX = WindowWidth(#mainWindow) / mainWindow_WidthIni : ScaleY = WindowHeight(#mainWindow) / mainWindow_HeightIni
ResizeGadget(#Txt_1, ScaleX * 10, ScaleY * 10, ScaleX * 50, ScaleY * 25)
ResizeGadget(#Txt_CLOCK, ScaleX * 65, ScaleY * 10, ScaleX * 60, ScaleY * 25)
ResizeGadget(#Btn_Extract, ScaleX * 410, ScaleY * 10, ScaleX * 80, ScaleY * 30)
ResizeGadget(#Edit_1, ScaleX * 10, ScaleY * 50, ScaleX * 480, ScaleY * 90)
EndProcedure
Procedure Open_mainWindow(X = 0, Y = 0, Width = 500, Height = 180)
OpenWindow(#mainWindow, X, Y, Width, Height, "Shows the progress of extracting 7z files with ProgressBar", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
TextGadget(#Txt_1, 10, 10, 50, 25, "Clock:", #SS_CENTERIMAGE)
TextGadget(#Txt_CLOCK, 65, 10, 60, 25, "8:18:18", #PB_Text_Center | #SS_CENTERIMAGE)
ButtonGadget(#Btn_Extract, 410, 10, 80, 30, "Extract")
EditorGadget(#Edit_1, 10, 50, 480, 90)
AddGadgetItem(#Edit_1, -1, "Action Log...")
StatusBar_mainWindow()
CreateThread(@update_clock(),0)
BindEvent(#PB_Event_SizeWindow, @Resize_mainWindow(), #mainWindow)
PostEvent(#PB_Event_SizeWindow, #mainWindow, 0)
EndProcedure
Open_mainWindow()
;- Main Program
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
FreeThread(*thr7zip)
Break
Case #MyEvent_7zip_Start
SetGadgetText(#Edit_1, FreeString(EventData()))
Case #MyEvent_7zip_Doing
SetGadgetText(#Edit_1, FreeString(EventData()))
Case #MyEvent_7zip_Finished
SetGadgetText(#Edit_1, FreeString(EventData()))
Case #MyEvent_7zip_Validate
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn_Extract
If Not IsThread(*thr7zip\ThreadID)
DoExtract(*thr7zip, "D:\my-files\a1.7z", "D:\ab c\d ef", "mypass")
EndIf
EndSelect
EndSelect
ForEver
DataSection
file_7zip:
IncludeBinary "7za.exe"
file_7zip_end:
EndDataSection