omikron48 Posted January 31, 2010 Share Posted January 31, 2010 Recently, I made an upload script so I can push files onto our servers using queued uploads. I did it so I could just leave my workstation uploading files all night and tell which uploads failed when I checked it in the morning. Thing is, I tried making an interrupt hotkey to stop the upload script so I could terminate it early. From my observation, the hotkey doesn't interrupt my script when it's in the middle of executing FileCopy. The script interrupt only triggers after the FileCopy finishes. So my question are: Is FileCopy a "blocking" function as defined in HotKeySet? Is there a way to cut my upload early without resorting to a file by file copy script? Is a file by file copy better than just copying a whole directory at once? Link to comment Share on other sites More sharing options...
KaFu Posted January 31, 2010 Share Posted January 31, 2010 (edited) Yep, the standard FileCopy() is a blocking function.Looking into the MSDN documentation of CopyFileEx (for which there are UDFs around), I see that you can issue a PROGRESS_CANCEL using the CopyProgressRoutine.Edit: Searching the forum brought up these two posts providing methods to cancel running file copy functions:By Yashied (method 1): #717740By rasim (long time not seen!): #568177 Edited January 31, 2010 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
omikron48 Posted January 31, 2010 Author Share Posted January 31, 2010 Forgot to add DirCopy too, since I also upload whole folders other than single files. Does CopyFileEx work on directories too? Or do I resort to doing a file by file copy using CopyFileEx? Link to comment Share on other sites More sharing options...
KaFu Posted January 31, 2010 Share Posted January 31, 2010 I assume it will accept wildcards. So DirCreate ( "path" ) and something like CopyFileEx(*.*) might do. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
omikron48 Posted February 1, 2010 Author Share Posted February 1, 2010 (edited) I can't seem to make _WinAPI_CopyFileEx work for me. Even a simple filecopy to a parent folder fails. Here's my trial code: expandcollapse popup#include <Constants.au3> #include <File.au3> #include <Misc.au3> #include <WinAPIEx.au3> Opt("MustDeclareVars", 1) Global $ininame = "_" & StringReplace(@ScriptName, ".exe", "") & ".ini" Global $section = "Options" ;check if .ini file exists If Not FileExists($ininame) Then MsgBox(0x2030, "Error", "No """ & $ininame & """! Writing empty .ini file.") _CreateINI() Exit EndIf Global $hotkey = IniRead($ininame, $section, "InterruptKey", "{PAUSE}") Global $tooltipx = IniRead($ininame, $section, "ToolTipX", @DesktopWidth) Global $tooltipy = IniRead($ininame, $section, "ToolTipY", @DesktopHeight) Global $targetpath = IniRead($ininame, $section, "TargetPath", "Error") Global $listpath = IniRead($ininame, $section, "ListPath", "Error") Global $logpath = IniRead($ininame, $section, "LogPath", "Error") Global $interrupt = 0 Global $pass = 0 Global $fail = 0 Global $fhandle = 0 Global $targets Global $title = "" Global $text = "" ;check input in .ini file If StringCompare($targetpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid TargetPath!") Exit ElseIf StringCompare($listpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid ListPath!") Exit ElseIf StringCompare($logpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid LogPath!") Exit EndIf ;check that file/folder to be copied and list of copy locations exist If FileExists($targetpath) == 0 Then MsgBox(0x2000, "Error", "TargetPath does not exist!") Exit ElseIf FileExists($listpath) == 0 Then MsgBox(0x2000, "Error", "ListPath does not exist!") Exit EndIf HotKeySet($hotkey, "_SetInterrupt") Global $hProgressRoutine ;read list fo copy locations into array If _FileReadToArray($listpath, $targets) Then Local $avgtime = 0 Local $time = 0 Local $start = TimerInit() Local $i _WriteLog("Starting Log: " & _GetDate() & " " & _GetTime()) ;iterate for each copy location For $i = 1 To $targets[0] If $interrupt Then ExitLoop EndIf ;recalculate average after first upload If $i <> 1 Then $avgtime = $time / ($i - 1) EndIf ;for display purposes (currently unused) $title = StringReplace(@ScriptName, ".exe", "") & " (" & $i & "/" & $targets[0] & ")" & " [P: " & $pass & " F: " & $fail & "]" $text = "Copy To: " & $targets[$i] & @CRLF & "Started: " & _GetTime() & " Avg Time: " & _ConvertTime($avgtime) If FileExists($targets[$i]) == 0 Then DirCreate($targets[$i]) EndIf $hProgressRoutine = DllCallbackRegister('_Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;ptr') If _WinAPI_CopyFileEx(FileGetShortName($targetpath), FileGetShortName($targets[$i]), DllCallBackGetPtr($hProgressRoutine)) Then _WriteLog("[" & _GetTime() & "] SUCCESS FILE COPY: " & $targets[$i]) $pass += 1 Else _WriteLog("[" & _GetTime() & "] " & @TAB & "FAILED FILE COPY: " & $targets[$i]) $fail += 1 EndIf DllCallbackFree($hProgressRoutine) $time = TimerDiff($start) Next Else MsgBox(0x2000, "Error", "Unable to generate targets list!") EndIf ;called on script close Func OnAutoItExit() _WriteLog("Ending Log: " & _GetDate() & " " & _GetTime() & " [P: " & $pass & " F: " & $fail & "]") EndFunc Func _Progress($iTotalFileSize, $iTotalBytesTransferred, $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $iData) If $interrupt == 1 Then _WriteLog("[" & _GetTime() & "] UPLOAD INTERRUPTED!!!") Return $PROGRESS_CANCEL Else Return $PROGRESS_CONTINUE EndIf EndFunc Func _SetInterrupt() $interrupt = 1 Sleep(3000) EndFunc ;creates default .ini file Func _CreateINI() IniWrite($ininame, $section, "InterruptKey", "{PAUSE}") IniWrite($ininame, $section, "ToolTipX", "") IniWrite($ininame, $section, "ToolTipY", "") IniWrite($ininame, $section, "TargetPath", "") IniWrite($ininame, $section, "ListPath", "") IniWrite($ininame, $section, "LogPath", "") EndFunc ;writes line to log file Func _WriteLog($msg) $fhandle = FileOpen($logpath, 9) FileWriteLine($fhandle, $msg) FileClose($fhandle) EndFunc ;returns current date Func _GetDate() Return @YEAR & "-" & @MON & "-" & @MDAY EndFunc ;returns time of day Func _GetTime() Return @HOUR & ":" & @MIN & ":" & @SEC EndFunc ;converts milliseconds into Dd:HHh:MMm:SSs Func _ConvertTime($millis) Local $days = Int($millis / 86400000) $millis -= $days * 86400000 Local $hours = Int($millis / 3600000) $millis -= $hours * 3600000 Local $minutes = Int($millis / 60000) $millis -= $minutes * 60000 Local $seconds = Int($millis / 1000) $millis -= $seconds * 1000 Local $result = "" If $days > 0 Then $result &= $days & "d:" EndIf If $hours > 0 Then $result &= StringFormat("%.2d", $hours) & "h:" EndIf If $minutes > 0 Then $result &= StringFormat("%.2d", $minutes) & "m:" EndIf If $seconds > 0 Then $result &= StringFormat("%.2d", $seconds) & "s" Else $result &= "00s" EndIf Return $result EndFunc Here's my working script that uses FileCopy and DirCopy: expandcollapse popup#include <File.au3> Opt("MustDeclareVars", 1) Global $ininame = "_" & StringReplace(@ScriptName, ".exe", "") & ".ini" Global $section = "Options" If Not FileExists($ininame) Then MsgBox(0x2030, "Error", "No """ & $ininame & """! Writing empty .ini file.") _CreateINI() Exit EndIf Global $hotkey = IniRead($ininame, $section, "InterruptKey", "{PAUSE}") Global $tooltipx = IniRead($ininame, $section, "ToolTipX", @DesktopWidth) Global $tooltipy = IniRead($ininame, $section, "ToolTipY", @DesktopHeight) Global $targetpath = IniRead($ininame, $section, "TargetPath", "Error") Global $listpath = IniRead($ininame, $section, "ListPath", "Error") Global $logpath = IniRead($ininame, $section, "LogPath", "Error") Global $interrupt = 0 Global $pass = 0 Global $fail = 0 Global $fhandle = 0 Global $targets If StringCompare($targetpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid TargetPath!") Exit ElseIf StringCompare($listpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid ListPath!") Exit ElseIf StringCompare($logpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid LogPath!") Exit EndIf If FileExists($targetpath) == 0 Then MsgBox(0x2000, "Error", "TargetPath does not exist!") Exit ElseIf FileExists($listpath) == 0 Then MsgBox(0x2000, "Error", "ListPath does not exist!") Exit EndIf HotKeySet($hotkey, "_SetInterrupt") If _FileReadToArray($listpath, $targets) Then Local $avgtime = 0 Local $time = 0 Local $start = TimerInit() Local $i _WriteLog("Starting Log: " & _GetDate() & " " & _GetTime()) For $i = 1 To $targets[0] If $interrupt Then ExitLoop EndIf If $i <> 1 Then $avgtime = $time / ($i - 1) EndIf ToolTip("Copy To: " & $targets[$i] & @CRLF & "Started: " & _GetTime() & " Avg Time: " & _ConvertTime($avgtime), $tooltipx, $tooltipy, StringReplace(@ScriptName, ".exe", "") & " (" & $i & "/" & $targets[0] & ")" & " [P: " & $pass & " F: " & $fail & "]", 0, 4) If StringInStr(FileGetAttrib($targetpath), "D") Then If DirCopy($targetpath, $targets[$i], 1) Then _WriteLog("[" & _GetTime() & "] SUCCESS DIR COPY: " & $targets[$i]) $pass += 1 Else _WriteLog("[" & _GetTime() & "] " & @TAB & "FAILED DIR COPY: " & $targets[$i]) $fail += 1 EndIf Else If FileCopy($targetpath, $targets[$i], 9) Then _WriteLog("[" & _GetTime() & "] SUCCESS FILE COPY: " & $targets[$i]) $pass += 1 Else _WriteLog("[" & _GetTime() & "] " & @TAB & "FAILED FILE COPY: " & $targets[$i]) $fail += 1 EndIf EndIf $time = TimerDiff($start) ToolTip("") Next Else MsgBox(0x2000, "Error", "Unable to generate targets list!") EndIf Func OnAutoItExit() _WriteLog("Ending Log: " & _GetDate() & " " & _GetTime() & " [P: " & $pass & " F: " & $fail & "]") EndFunc Func _SetInterrupt() $interrupt = 1 _WriteLog("[" & _GetTime() & "] UPLOAD INTERRUPTED!!!") Tooltip("Please wait...", $tooltipx, $tooltipy, "Upload Interrupted", 0, 4) Sleep(3000) EndFunc Func _CreateINI() IniWrite($ininame, $section, "InterruptKey", "{PAUSE}") IniWrite($ininame, $section, "ToolTipX", "") IniWrite($ininame, $section, "ToolTipY", "") IniWrite($ininame, $section, "TargetPath", "") IniWrite($ininame, $section, "ListPath", "") IniWrite($ininame, $section, "LogPath", "") EndFunc Func _WriteLog($msg) $fhandle = FileOpen($logpath, 9) FileWriteLine($fhandle, $msg) FileClose($fhandle) EndFunc Func _GetDate() Return @YEAR & "-" & @MON & "-" & @MDAY EndFunc Func _GetTime() Return @HOUR & ":" & @MIN & ":" & @SEC EndFunc Func _ConvertTime($millis) Local $days = Int($millis / 86400000) $millis -= $days * 86400000 Local $hours = Int($millis / 3600000) $millis -= $hours * 3600000 Local $minutes = Int($millis / 60000) $millis -= $minutes * 60000 Local $seconds = Int($millis / 1000) $millis -= $seconds * 1000 Local $result = "" If $days > 0 Then $result &= $days & "d:" EndIf If $hours > 0 Then $result &= StringFormat("%.2d", $hours) & "h:" EndIf If $minutes > 0 Then $result &= StringFormat("%.2d", $minutes) & "m:" EndIf If $seconds > 0 Then $result &= StringFormat("%.2d", $seconds) & "s" Else $result &= "00s" EndIf Return $result EndFunc Contents of my input files are as follows... _Upload_File2.ini (must have same name as compiled script) [Options] InterruptKey={PAUSE} ToolTipX=1024 ToolTipY=675 TargetPath=D:\[Upload]\_Upload\W2K3_Patch\6_WindowsServer2003-KB923561-x86-ENU.exe ListPath=servers.txt LogPath=upload.txt servers.txt D:\[Upload]\_Upload\6_WindowsServer2003-KB923561-x86-ENU.exe Edited February 1, 2010 by omikron48 Link to comment Share on other sites More sharing options...
KaFu Posted February 1, 2010 Share Posted February 1, 2010 (edited) Tweaked your script a little to work locally for testing. This works for me: expandcollapse popup#include <Constants.au3> #include <File.au3> #include <Misc.au3> #include <WinAPIEx.au3> Opt("MustDeclareVars", 1) ;Global $ininame = "_" & StringReplace(@ScriptName, ".exe", "") & ".ini" Global $ininame = "_Upload_File2.ini" Global $section = "Options" ;check if .ini file exists If Not FileExists($ininame) Then MsgBox(0x2030, "Error", "No """ & $ininame & """! Writing empty .ini file.") _CreateINI() Exit EndIf Global $hotkey = IniRead($ininame, $section, "InterruptKey", "{PAUSE}") Global $tooltipx = IniRead($ininame, $section, "ToolTipX", @DesktopWidth) Global $tooltipy = IniRead($ininame, $section, "ToolTipY", @DesktopHeight) Global $sourcepath = IniRead($ininame, $section, "sourcepath", "Error") Global $listpath = IniRead($ininame, $section, "ListPath", "Error") Global $logpath = IniRead($ininame, $section, "LogPath", "Error") Global $interrupt = 0 Global $pass = 0 Global $fail = 0 Global $fhandle = 0 Global $targets Global $title = "" Global $text = "" Global $target_drive, $target_dir ;check input in .ini file If StringCompare($sourcepath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid sourcepath!") Exit ElseIf StringCompare($listpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid ListPath!") Exit ElseIf StringCompare($logpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid LogPath!") Exit EndIf ;check that file/folder to be copied and list of copy locations exist If FileExists($sourcepath) == 0 Then MsgBox(0x2000, "Error", "sourcepath does not exist!") Exit ElseIf FileExists($listpath) == 0 Then MsgBox(0x2000, "Error", "ListPath does not exist!") Exit EndIf HotKeySet($hotkey, "_SetInterrupt") Global $hProgressRoutine ;read list fo copy locations into array If _FileReadToArray($listpath, $targets) Then Local $avgtime = 0 Local $time = 0 Local $start = TimerInit() Local $i _WriteLog("Starting Log: " & _GetDate() & " " & _GetTime()) ;iterate for each copy location For $i = 1 To $targets[0] If $interrupt Then ExitLoop EndIf ;recalculate average after first upload If $i <> 1 Then $avgtime = $time / ($i - 1) EndIf ;for display purposes (currently unused) $title = StringReplace(@ScriptName, ".exe", "") & " (" & $i & "/" & $targets[0] & ")" & " [P: " & $pass & " F: " & $fail & "]" $text = "Copy To: " & $targets[$i] & @CRLF & "Started: " & _GetTime() & " Avg Time: " & _ConvertTime($avgtime) $target_dir = StringLeft($targets[$i],StringInStr($targets[$i],"\",0,-1)) $target_drive = StringLeft($targets[$i],3) if FileExists($target_drive) Then If not FileExists($target_dir) Then DirCreate($target_dir) EndIf Else MsgBox(16, "Error", "Target Drive not found!") endif $hProgressRoutine = DllCallbackRegister('_Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;ptr') If _WinAPI_CopyFileEx(FileGetShortName($sourcepath), FileGetShortName($targets[$i]), DllCallbackGetPtr($hProgressRoutine)) Then _WriteLog("[" & _GetTime() & "] SUCCESS FILE COPY: " & $targets[$i]) $pass += 1 Else _WriteLog("[" & _GetTime() & "] " & @TAB & "FAILED FILE COPY: " & $targets[$i]) $fail += 1 EndIf DllCallbackFree($hProgressRoutine) $time = TimerDiff($start) Next Else MsgBox(0x2000, "Error", "Unable to generate targets list!") EndIf ;called on script close Func OnAutoItExit() _WriteLog("Ending Log: " & _GetDate() & " " & _GetTime() & " [P: " & $pass & " F: " & $fail & "]") EndFunc ;==>OnAutoItExit Func _Progress($iTotalFileSize, $iTotalBytesTransferred, $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $iData) If $interrupt == 1 Then _WriteLog("[" & _GetTime() & "] UPLOAD INTERRUPTED!!!") Return $PROGRESS_CANCEL Else _WriteLog("[" & _GetTime() & "] " & $iTotalFileSize & " / " & $iTotalBytesTransferred) Return $PROGRESS_CONTINUE EndIf EndFunc ;==>_Progress Func _SetInterrupt() $interrupt = 1 Sleep(3000) EndFunc ;==>_SetInterrupt ;creates default .ini file Func _CreateINI() IniWrite($ininame, $section, "InterruptKey", "{PAUSE}") IniWrite($ininame, $section, "ToolTipX", "") IniWrite($ininame, $section, "ToolTipY", "") IniWrite($ininame, $section, "sourcepath", "") IniWrite($ininame, $section, "ListPath", "") IniWrite($ininame, $section, "LogPath", "") EndFunc ;==>_CreateINI ;writes line to log file Func _WriteLog($msg) $fhandle = FileOpen($logpath, 9) FileWriteLine($fhandle, $msg) FileClose($fhandle) EndFunc ;==>_WriteLog ;returns current date Func _GetDate() Return @YEAR & "-" & @MON & "-" & @MDAY EndFunc ;==>_GetDate ;returns time of day Func _GetTime() Return @HOUR & ":" & @MIN & ":" & @SEC EndFunc ;==>_GetTime ;converts milliseconds into Dd:HHh:MMm:SSs Func _ConvertTime($millis) Local $days = Int($millis / 86400000) $millis -= $days * 86400000 Local $hours = Int($millis / 3600000) $millis -= $hours * 3600000 Local $minutes = Int($millis / 60000) $millis -= $minutes * 60000 Local $seconds = Int($millis / 1000) $millis -= $seconds * 1000 Local $result = "" If $days > 0 Then $result &= $days & "d:" EndIf If $hours > 0 Then $result &= StringFormat("%.2d", $hours) & "h:" EndIf If $minutes > 0 Then $result &= StringFormat("%.2d", $minutes) & "m:" EndIf If $seconds > 0 Then $result &= StringFormat("%.2d", $seconds) & "s" Else $result &= "00s" EndIf Return $result EndFunc ;==>_ConvertTime Maybe you should comment this line out: _WriteLog("[" & _GetTime() & "] " & $iTotalFileSize & " / " & $iTotalBytesTransferred) and for testing I hardcoded the ini name to _Upload_File2.ini Servers.txt: C:\temp\_test\[upload]\autoit-v3-setup.exe _Upload_File2.ini: [Options] InterruptKey={PAUSE} ToolTipX=1024 ToolTipY=675 sourcepath=C:\temp\_test\autoit-v3-setup.exe ListPath=servers.txt LogPath=upload.txt Edited February 1, 2010 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
omikron48 Posted February 2, 2010 Author Share Posted February 2, 2010 (edited) I got it working, somewhat... The only problem is that it only supports single file copies and not directory copies. The only thing that's improved is I now have a progress indicator. It seems I can't set a hotkey to toggle a flag to interrupt CopyFileEx. I would like to be able to set different hotkeys since I run multiple instances of my script at a time, up to 10 at times. Yashied's sample uses _IsPressed but it would be harder to set from an .ini file since _IsPressed uses key values and not strings. I also need to figure out a way to adjust the progress indicator to track progress on transfer of a whole directory while using CopyFileEx and DirCreate recursively on its contents. In any case, here's the working script I got so far. I re-included the information display. expandcollapse popup#include <File.au3> #include <WinAPIEx.au3> Opt("MustDeclareVars", 1) OnAutoItExitRegister("_OnClose") Global $scriptname = StringReplace(@ScriptName, ".exe", "") Global $ininame = "_" & $scriptname & ".ini" Global $section = "Options" ;check if .ini file exists If Not FileExists($ininame) Then MsgBox(0x2030, "Error", "No """ & $ininame & """! Writing empty .ini file.") _CreateINI() Exit EndIf Global $hotkey = IniRead($ininame, $section, "InterruptKey", "{PAUSE}") Global $tooltipx = IniRead($ininame, $section, "ToolTipX", @DesktopWidth) Global $tooltipy = IniRead($ininame, $section, "ToolTipY", @DesktopHeight) Global $sourcepath = IniRead($ininame, $section, "SourcePath", "Error") Global $listpath = IniRead($ininame, $section, "ListPath", "Error") Global $logpath = IniRead($ininame, $section, "LogPath", "Error") Global $interrupt = 0 Global $pass = 0 Global $fail = 0 Global $fhandle = 0 Global $targets Global $targetdrive Global $targetdir Global $title = "" Global $text = "" ;check input in .ini file If StringCompare($sourcepath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid SourcePath!") Exit ElseIf StringCompare($listpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid ListPath!") Exit ElseIf StringCompare($logpath, "Error") == 0 Then MsgBox(0x2000, "Error", "Invalid LogPath!") Exit EndIf ;check that file/folder to be copied and list of copy locations exist If FileExists($sourcepath) == 0 Then MsgBox(0x2000, "Error", "TargetPath does not exist!") Exit ElseIf FileExists($listpath) == 0 Then MsgBox(0x2000, "Error", "ListPath does not exist!") Exit EndIf HotKeySet($hotkey, "_SetInterrupt") Global $hProgressRoutine ;read list fo copy locations into array If _FileReadToArray($listpath, $targets) Then Local $avgtime = 0 Local $time = 0 Local $start = TimerInit() Local $i _WriteLog("Starting Log: " & _GetDate() & " " & _GetTime()) ;iterate for each copy location For $i = 1 To $targets[0] If $interrupt Then ExitLoop EndIf ;recalculate average after first upload If $i <> 1 Then $avgtime = $time / ($i - 1) EndIf $targetdir = StringLeft($targets[$i], StringInStr($targets[$i], "\", 0, -1)) ; If StringCompare(StringLeft($targets[$i], 2), "\\") == 0 Then ; $targetdrive = StringLeft($targets[$i], StringInStr($targets[$i], "\", 0, 3) - 1) ; Else ; $targetdrive = StringLeft($targets[$i], 3) ; EndIf If Not FileExists($targetdir) Then If Not DirCreate($targetdir) Then _WriteLog("[" & _GetTime() & "] " & @TAB & "UNABLE TO CREATE: " & $targetdir) ContinueLoop EndIf EndIf ;for display purposes (currently unused) $title = $scriptname & " (" & $i & "/" & $targets[0] & ")" & " [P: " & $pass & " F: " & $fail & "]" $text = "Copy To: " & $targets[$i] & @CRLF & "Started: " & _GetTime() & " Avg Time: " & _ConvertTime($avgtime) $hProgressRoutine = DllCallbackRegister('_Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;ptr') ToolTip($text, $tooltipx, $tooltipy, $title) If _WinAPI_CopyFileEx($sourcepath, $targets[$i], DllCallBackGetPtr($hProgressRoutine)) Then _WriteLog("[" & _GetTime() & "] SUCCESS FILE COPY: " & $targets[$i]) $pass += 1 Else _WriteLog("[" & _GetTime() & "] " & @TAB & "FAILED FILE COPY: " & $targets[$i]) $fail += 1 EndIf DllCallbackFree($hProgressRoutine) $time = TimerDiff($start) ToolTip("") Next Else MsgBox(0x2000, "Error", "Unable to generate targets list!") EndIf ;called on script close Func _OnClose() _WriteLog("Ending Log: " & _GetDate() & " " & _GetTime() & " [P: " & $pass & " F: " & $fail & "]") EndFunc Func _Progress($iTotalFileSize, $iTotalBytesTransferred, $iStreamSize, $iStreamBytesTransferred, $iStreamNumber, $iCallbackReason, $hSourceFile, $hDestinationFile, $iData) ToolTip($text & " Progress: " & Round($iTotalBytesTransferred / $iTotalFileSize * 100, 1) & '%', $tooltipx, $tooltipy, $title, 0 ,4) If $interrupt == 1 Then _WriteLog("[" & _GetTime() & "] UPLOAD INTERRUPTED!!!") Return $PROGRESS_CANCEL Else Return $PROGRESS_CONTINUE EndIf EndFunc Func _SetInterrupt() $interrupt = 1 EndFunc ;creates default .ini file Func _CreateINI() IniWrite($ininame, $section, "InterruptKey", "{PAUSE}") IniWrite($ininame, $section, "ToolTipX", "") IniWrite($ininame, $section, "ToolTipY", "") IniWrite($ininame, $section, "SourcePath", "") IniWrite($ininame, $section, "ListPath", "") IniWrite($ininame, $section, "LogPath", "") EndFunc ;writes line to log file Func _WriteLog($msg) $fhandle = FileOpen($logpath, 9) FileWriteLine($fhandle, $msg) FileClose($fhandle) EndFunc ;returns current date Func _GetDate() Return @YEAR & "-" & @MON & "-" & @MDAY EndFunc ;returns time of day Func _GetTime() Return @HOUR & ":" & @MIN & ":" & @SEC EndFunc ;converts milliseconds into Dd:HHh:MMm:SSs Func _ConvertTime($millis) Local $days = Int($millis / 86400000) $millis -= $days * 86400000 Local $hours = Int($millis / 3600000) $millis -= $hours * 3600000 Local $minutes = Int($millis / 60000) $millis -= $minutes * 60000 Local $seconds = Int($millis / 1000) $millis -= $seconds * 1000 Local $result = "" If $days > 0 Then $result &= $days & "d:" EndIf If $hours > 0 Then $result &= StringFormat("%.2d", $hours) & "h:" EndIf If $minutes > 0 Then $result &= StringFormat("%.2d", $minutes) & "m:" EndIf If $seconds > 0 Then $result &= StringFormat("%.2d", $seconds) & "s" Else $result &= "00s" EndIf Return $result EndFunc Edited February 2, 2010 by omikron48 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now