ShellFileOperation() - Basic Wrapper A shell function that can be called to Copy / Move / Delete / Rename File(s). Displays an animated progress bar if the task is time consuming. Progress bar is useful when operating on slower media like Digital Cameras or when dealing with huge files like video. I have wrapped only the basic functionality. Hopefully, I should be updating it in near future. For customised needs refer MSDN. MSDN Reference: SHFileOperation Function SHFILEOPSTRUCT Structure How To Use the Animated Copy Functions in Windows 95/98/Me Parameters: The first parameter can be only one of the following:
Code:
FO_MOVE := 0x1 FO_COPY := 0x2 FO_DELETE := 0x3 FO_RENAME := 0x4
The Second / Third parameters should be strings containing path to Source and Destination Source may contain Wildcards but not Target Source can be a list of files delimited with pipe. ( The wrapper function replaces pipe characters with NULL ) Always use fullpath and not relative. The fouth parameter can contain a combination of values for which please refer MSDN Usage Examples:
Code:
ShellFileOperation( 0x2, A_AhkPath, A_DeskTop ) ; Copy a Single file ShellFileOperation( 0x2, "C:\Program Files\AutoHotkey", A_DeskTop ) ; Copy the whole folder
Advanced Example: ( Along with the wrapped Shell Function ) The following code performs a recursive scan on the Temporary Internet Files folder and creates a pipe delimited list of .gif files and passes it to the wrapper function which copies the files to the script's subfolder named Gif_Files.
Code (Expand):
SetBatchLines -1 SetWorkingDir, %A_ScriptDir% imgPath := A_Temp . "orary Internet Files" Loop, %imgPath%\*.gif, 0 ,1 Source .= A_LoopFileLongPath "|" Target := A_ScriptDir "\Gif_Files" flags := ( FOF_RENAMEONCOLLISION := 0x8 ) | ( FOF_NOCONFIRMMKDIR := 0x200 ) ShellFileOperation( 0x2, Source, Target, flags ) Return ShellFileOperation( fileO=0x0, fSource="", fTarget="", flags=0x0, ghwnd=0x0 ) { If ( SubStr(fSource,0) != "|" ) fSource := fSource . "|" If ( SubStr(fTarget,0) != "|" ) fTarget := fTarget . "|" fsPtr := &fSource Loop, % StrLen(fSource) If ( *(fsPtr+(A_Index-1)) = 124 ) DllCall( "RtlFillMemory", UInt, fsPtr+(A_Index-1), Int,1, UChar,0 ) ftPtr := &fTarget Loop, % StrLen(fTarget) If ( *(ftPtr+(A_Index-1)) = 124 ) DllCall( "RtlFillMemory", UInt, ftPtr+(A_Index-1), Int,1, UChar,0 ) VarSetCapacity( SHFILEOPSTRUCT, 30, 0 ) ; Encoding SHFILEOPSTRUCT NextOffset := NumPut( ghwnd, &SHFILEOPSTRUCT ) ; hWnd of calling GUI NextOffset := NumPut( fileO, NextOffset+0 ) ; File operation NextOffset := NumPut( fsPtr, NextOffset+0 ) ; Source file / pattern NextOffset := NumPut( ftPtr, NextOffset+0 ) ; Target file / folder NextOffset := NumPut( flags, NextOffset+0, 0, "Short" ) ; options DllCall( "Shell32\SHFileOperationA", UInt,&SHFILEOPSTRUCT ) Return NumGet( NextOffset+0 ) }
The flag FOF_NOCONFIRMMKDIR supresses the user confirmation for subfolder creation and FOF_RENAMEONCOLLISION takes care of renaming similar filenames. FOF_RENAMEONCOLLISION: For example I recursively scanned for README.TXT in drive C: and I had a list of 667 files. When copied to the same folder with FOF_RENAMEONCOLLISION, The 1st file was README.TXT, 2nd file was Copy of README.TXT, 3rd file was Copy (1) of README.TXT ... and the last file was Copy (665) of README.TXT Note: You see a progress bar only if the above takes more than a couple of seconds