Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Copy folders with Progress Bar


  • Please log in to reply
10 replies to this topic
Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011
I have the following code to copy a couple folders to my F Drive.

Sometimes the folders are big, therefore I would like to create a progress bar that shows me how much is complete during the copy process. I've tried looking at LiveWindows but couldn't get it working in Windows 7.

Is there anyway to identify the % of a file copied?

global dest_folder := "F:\"

Source1 := "C:\Users\BD\Desktop\FoldA"
Source2 := "C:\Users\BD\Desktop\FoldB"


!h::
Run, %dest_folder%

copy_folder(Source1)
copy_folder(Source2)

return



copy_folder(Source)
{
folder_name := current_date()
SplitPath, Source,,,, name_no_ext
Dest := dest_folder folder_name "\" name_no_ext

FileCopyDir, %Source%, %Dest%, 0 ;do not overwrite
}

current_date()
{
FormatTime, month,, MMM
FormatTime, day,, dd
FormatTime, year,, yyyy
FormatTime, hour,, H
FormatTime, minute,, mm
period := "am"

if (hour >= 12)
   period := "pm"

if (hour > 12)
   hour := hour - 12

new_folder := month " " day ", " year " " hour minute " " period

return  new_folder
}


kdoske
  • Members
  • 138 posts
  • Last active: Nov 06 2012 01:58 AM
  • Joined: 17 Dec 2008
just use FileGetSize before copy and then use settimer to check the size of the file in the new location ever second or so. While its in the timer update the progress bar. You would need to do the math yourself to get the percentage for the bar. A very basic example of what I mean. Code is would not work but it will give you the road map I think.


copyfile:
filegetsize, source1
filecopydir,
settimer, blah, 1000
return

blah:
filegetsize, source2
percent math between size of source 1 and source 2
progress, percentcomplete
if(percentcomplete = 100)
{
settimer, blah, off
msgbox, complete
}
return

Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009
In your script, you copy a folder to another folder that you have created.

Since you use 'FileCopyDir' there is no intermediate results.

If you were to take the job of copying over for yourself, you could use loop (files & folders) to read the name of each entry in 'A_LoopFileName'.

Along with 'A_LoopFileName' there are variables related to the file size.

You could also get the count of how many files exist or how many files still need to be copied.


To ge the filspace required without doing any copying just use use (files & folders) and add up the file sizes.

MilesAhead
  • Members
  • 578 posts
  • Last active: Feb 29 2016 05:15 PM
  • Joined: 21 Jan 2009
If you have copious free time you may want to mess around with IFileOperation Interface

edit: the bad news is it requires at least Vista. The good news is I believe on W7 it may do the progress on Taskbar Button stuff for you. But I'd look for example code to make sure. If you're exclusively on XP then of course it's useless. :)

"Some people, when confronted with a problem, think I know, I'll use regular expressions.  Now they have two problems."

- Jamie Zawinski


maul.esel
  • Members
  • 790 posts
  • Last active: Jan 05 2013 09:26 PM
  • Joined: 28 Feb 2011
I made wrappers for the IOperationsProgressDialog and IProgressDialog interfaces as part of CCF. The docs should be up here, but seem to be down for an unknown reason. Posted Image

Edit: wrong URL, sorry. docs for IOperationsProgressDialog and docs for IProgressDialog (both work on XP already).
Join the discussion on The future of AutoHotkey
Posted Image Visit me on github Posted Image
Win7 HP SP1 64bit | AHK_L U 64bit

Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011

If you were to take the job of copying over for yourself,


I'm assuming someone has already made a function to copy all the files and sub-folders over individually? Do you know where I could find this?

MilesAhead
  • Members
  • 578 posts
  • Last active: Feb 29 2016 05:15 PM
  • Joined: 21 Jan 2009
Since FileCopyDir function already does that, the only reason anyone would do it manually would be to show progress. Therefore your best best is likely to search on "Progress"

edit: doesn't seem to be many hits. Anyway, to start you might take the easy way out and get the total number of files you are going to copy using Loop filepattern with a starting count of zero and just increment on every loop. Then either do the progress math using that number or figure how many files to get so much percentage increase.

By playing around with an easy case you'll learn how to do it. Then you can add bells and whistles as suggested like total file size considerations. Basic idea is to get an easy test case to work. Then you'll see why your first idea sucks and you'll have an idea how to do it right the second time. :)

"Some people, when confronted with a problem, think I know, I'll use regular expressions.  Now they have two problems."

- Jamie Zawinski


Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009

I'm assuming someone has already made a function to copy all the files and sub-folders over individually? Do you know where I could find this?


You assume incorrectly grasshopper. It is now >your< job to write this function.

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
Just search the forums for SHFileOperation. SKAN's version seems to be available still http://www.autohotke...ion#entry125953.

And here's another one from the ancient AHK_Basic days (may work though):
#NoEnv
Quelle := "D:\AHK"
Ziel := "E:\AHK_SAV"
MsgBox, % _CopyDirEx_(Quelle, Ziel, 2, "ahk,ini,txt")
ExitApp
; ------------------------------------------------------------------------------
; _CopyDirEx_()
;
; Funktion:
; Kopieren von Verzeichnissen mit erweiterter Funktionalität.
; 1. Gui mit Fortschrittsanzeige
; 2. Löschen des Zielverzeichnisses vor dem Kopieren
; 3. Auswahl bestimmter Dateien mittels Suchmuster
;
; Parameter:
; Source			 Quellverzeichnis
; Dest			   Zielverzeichnis
; Optional: Flag	 0 = Dateien im Zielverzeichnis nicht überschreiben
;				    1 = Dateien im Zielverzeichnis überschreiben
;				    2 = Zielverzeichnis ggf. vor dem Kopieren löschen
;				    Standard: 1
; Optional: Pattern  Dateiauswahlmuster (z.B. "*.ahk") oder Komma-getrennte
;				    Liste von Dateierweiterungen (z.B. "ahk,ini,hlp")
;				    Standard: "" = "*.*"
;				    Bei Vorgabe eines Suchmusters werden Ordner, die keine
;				    entsprechenden Dateien enthalten, nicht übernommen!
; Optional: Gui	  Guinummer
;				    Standard: 77
;
; Danksagung:
; Mein spezieller Dank gilt Superfraggle, ahklerner und tonne für
; [url="http://www.autohotkey.com/forum/post-143928.html"]http://www.autohotke...ost-143928.html[/url]
; ------------------------------------------------------------------------------
_CopyDirEx_( Source
		 , Dest
		 , Flag = 1
		 , Pattern = ""
		 , Gui = 77 )
{
   Global _CDE_Gui
   Global _CDE_PGB1
   Global _CDE_PGB2
   Global _CDE_TotalSize
   Global _CDE_CopiedFile
   Global _CDE_CopiedTotal
   Global _CDE_Cancel
   ; ---------------------------------------------------------------------------
   ; Statische Variablen
   Static OverWrite := 1
   Static DeleteDest := 2
   Static Callback := 0
   ; ---------------------------------------------------------------------------
   ; Sprachabhängige Konstanten
   Static TXGIN := " Copy"
   Static TXSIN := "Source:`t`t"
   Static TXDIN := "Destination:`t"
   Static TXCIN := "Cancel"
   Static TXTIN := "Total: "
   Static TXS1IN := "   Getting files ..."
   Static TXS2IN := "   File "
   Static TXS3IN := " of "
   Static TXS4IN := "   Done!"
   Static TXS5IN := "   Terminated!"
   Static TXM1IN := "Error while copying file "
   Static TXM2IN := "Size of source: "
   Static TXM3IN := "Size of copy: "
   Static TXM4IN := "Copying will be terminated!"
   Static TXG07 := " Kopieren"
   Static TXS07 := "Quelle:`t"
   Static TXD07 := "Ziel:`t"
   Static TXC07 := "Abbruch"
   Static TXT07 := "Gesamt: "
   Static TXS107 := "   Dateien werden ermittelt ..."
   Static TXS207 := "   Datei "
   Static TXS307 := " von "
   Static TXS407 := "   Fertig!"
   Static TXS507 := "   Abgebrochen!"
   Static TXM107 := "Fehler beim Kopieren der Datei "
   Static TXM207 := "Originalgröße: "
   Static TXM307 := "Größe der Kopie: "
   Static TXM407 := "Das Kopieren wird abgebrochen!"
   ; ---------------------------------------------------------------------------
   ; Gui
   Static T1
   ; ---------------------------------------------------------------------------
   ; Spracheinstellung
   LANG := "IN"
   If (SubStr(A_Language, 3) = "07") {
	  LANG := "07"
   }
   ; ---------------------------------------------------------------------------
   ; Parameter auswerten
   _CDE_Gui := Gui
   If (Pattern = "") {
	  Pattern := "*.*"
   } Else If InStr(Pattern, ",") {
	  MEXT := Pattern
	  Pattern := "*.*"
   }
   ; ---------------------------------------------------------------------------
   ; Zielverzeichnis ggf. löschen?
   If (Flag = DeleteDest) {
	  If (FileExist(Dest)) {
		 FileRemoveDir, %Dest% , 1
	  }
   }
   ; ---------------------------------------------------------------------------
   ; Gui
   Gui, %Gui%:Default
   Gui, +AlwaysOnTop +Toolwindow +OwnDialogs +LastFound +Label_CDE_Gui_
   Gui, Margin, 10, 10
   Gui, Add, Text, Section, % TXS%LANG% . Source
   Gui, Add, Text, xs y+5, % TXD%LANG% . Dest
   Gui, Add, Button, x330 ys w80 g_CDE_Gui_Close, % TXC%LANG%
   Gui, Add, Text, xs w400 vT1
   Gui, Add, Progress, xm y+3 wp v_CDE_PGB1 -Smooth, 0
   Gui, Add, Text, xm y+5 wp, % TXT%LANG%
   Gui, Add, Progress, xm y+3 wp v_CDE_PGB2 -Smooth, 0
   Gui, Add, StatusBar, , % TXS1%LANG%
   Gui, Show, , % TXG%LANG%
   ; ---------------------------------------------------------------------------
   ; Anzahl der Dateien und Gesamtgröße ermitteln
   _CDE_TotalSize := 0
   Files := 0
   Paths := ""
   Loop, %Source%\%Pattern%, % Pattern = "*.*" ? 1 : 0, 1
   {
	  If (Flag = 0) {
		 StringReplace, NewFile, A_LoopFileLongPath, %Source%, %Dest%
		 If (FileExist(NewFile)) {
		    Continue
		 }
	  }
	  If (MEXT) {
		 If A_LoopFileExt Not In %MEXT%
		    Continue
	  }
	  Paths .= A_LoopFileLongPath . "`n"
	  If !(InStr(FileExist(A_LoopFileLongPath), "D")) {
		 _CDE_TotalSize += A_LoopFileSize
		 Files++
	  }
   }
   ; ---------------------------------------------------------------------------
   ; Dateien kopieren
   If !(Callback) {
	  Callback :=RegisterCallback("_CDE_Progress")
   }
   _CDE_CopiedTotal := 0
   _CDE_Cancel := False
   Loop, Parse, Paths, `n
   {
	  If (A_Index > Files) {
		 Break
	  }
	  If (InStr(FileExist(A_LoopField), "D")) {
		 FileCreateDir, %A_LoopField%
		 Continue
	  }
	  SB_SetText(TXS2%LANG% . A_Index . TXS3%LANG% . Files)
	  FileGetSize, FileSize, %A_LoopField%
	  StringReplace, NewFile, A_LoopField, %Source%, %Dest%
	  SplitPath, NewFile, , Dir
	  If !(FileExist(Dir))
		 FileCreateDir, %Dir%
	  GuiControl, , T1, %A_LoopField%
	  GuiControl, , _CDE_PGB1, 0
	  _CDE_CopiedFile := 0
	  RetVal := DllCall("CopyFileEx"
					    , Str , A_LoopField
					    , Str , NewFile
					    , Uint, Callback
					    , Uint, 0
					    , Int, _CDE_Cancel
					    , Int, 0)
	  Sleep, -1
	  If (_CDE_Cancel) {
		 Break
	  }
	  If (RetVal = 0 Or ErrorLevel != 0 Or FileSize > _CDE_CopiedFile) {
		 MsgBox, 4112, _CopyDir_
			   ,  % TXM1%LANG% . NewFile . "!`n`n"
				  . "RetVal: " . RetVal . " *`n"
				  . "A_LastError: " . A_LastError . " *`n"
				  . TXM2%LANG% . FileSize . " *`n"
				  . TXM3%LANG% . _CDE_CopiedFile . " *`n`n"
				  . TXM4%LANG%
		 FileDelete, %NewFile%
		 Return False
	  }
	  _CDE_CopiedTotal += FileSize
   }
   ; ---------------------------------------------------------------------------
   ; Fertig!
   SB_SetText(_CDE_Cancel ? TXS5%LANG% : TXS4%LANG%)
   Sleep, 2000
   Gui, %Gui%:Destroy
   Return True
   ; ---------------------------------------------------------------------------
   _CDE_Gui_Close:
   _CDE_Gui_Escape:
   _CDE_Cancel := True
   Return
}
; ------------------------------------------------------------------------------
; Callback-Funktion für die Fortschrittsanzeige
_CDE_Progress(P1L, P1H, P2L, P2H, P3L, P3H, P4L, P4H, P5, P6, P7, P8, P9) {
   ; LARGE_INTEGER TotalFileSize (2 * Integer)
   ; LARGE_INTEGER TotalBytesTransferred (2 * Integer)
   ; LARGE_INTEGER StreamSize (2 * Integer)
   ; LARGE_INTEGER StreamBytesTransferred (2 * Integer)
   ; DWORD dwStreamNumber
   ; DWORD dwCallbackReason
   ; HANDLE hSourceFile
   ; HANDLE hDestinationFile
   ; LPVOID lpData
   Global _CDE_Gui
   Global _CDE_PGB1
   Global _CDE_PGB2
   Global _CDE_TotalSize
   Global _CDE_CopiedFile
   Global _CDE_CopiedTotal
   Global _CDE_Cancel
   FileSize := (P1H << 32) + P1L
   _CDE_CopiedFile := (P2H << 32) + P2L
   GuiControl, %_CDE_Gui%:, _CDE_PGB1
	  , % Round(_CDE_CopiedFile / FileSize * 100)
   GuiControl, %_CDE_Gui%:, _CDE_PGB2
	  , % Round((_CDE_CopiedFile + _CDE_CopiedTotal) / _CDE_TotalSize * 100)
   Return _CDE_Cancel
}

Prefer ahkscript.org for the time being.


MilesAhead
  • Members
  • 578 posts
  • Last active: Feb 29 2016 05:15 PM
  • Joined: 21 Jan 2009
Is it just me or is everything posted using Code tags double spaced?

"Some people, when confronted with a problem, think I know, I'll use regular expressions.  Now they have two problems."

- Jamie Zawinski


kdoske
  • Members
  • 138 posts
  • Last active: Nov 06 2012 01:58 AM
  • Joined: 17 Dec 2008

Is it just me or is everything posted using Code tags double spaced?


No, its me too. Its also annoying that the code blocks are not loaded in a compressed view like the old forum. I imagine its just growing pains of the new forum. Its already been addressed here.

http://www.autohotke...site-new-lines/