Danyfirex Posted April 11 Share Posted April 11 I was needing to copy some files something like a backup of a folder without overwrite file. I found in this thread a suggestion to use _WinAPI_ShellFileOperation but for my surprise it does overwrite files all the time 🤔. So I was checking MSDN and found out that IFileOperation implemented a nice operation flag to handle what I was needing(FOFX_KEEPNEWERFILE) so I just wrote this sample in case anyone was looking for it. expandcollapse popup#include <WinAPIShellEx.au3> ;~ Global Const $FOF_ALLOWUNDO = 0x40 ;~ Global Const $FOF_CONFIRMMOUSE = 0x2 ;~ Global Const $FOF_FILESONLY = 0x80 ;~ Global Const $FOF_MULTIDESTFILES = 0x1 ;~ Global Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000 ;~ Global Const $FOF_NOCONFIRMATION = 0x10 ;~ Global Const $FOF_NOCONFIRMMKDIR = 0x200 ;~ Global Const $FOF_NOCOPYSECURITYATTRIBS = 0x800 ;~ Global Const $FOF_NOERRORUI = 0x400 ;~ Global Const $FOF_NORECURSION = 0x1000 ;~ Global Const $FOF_RENAMEONCOLLISION = 0x8 ;~ Global Const $FOF_SILENT = 0x4 ;~ Global Const $FOF_SIMPLEPROGRESS = 0x100 ;~ Global Const $FOF_WANTMAPPINGHANDLE = 0x20 ;~ Global Const $FOF_WANTNUKEWARNING = 0x4000 Global Const $FOFX_ADDUNDORECORD = 0x20000000 Global Const $FOFX_NOSKIPJUNCTIONS = 0x00010000 Global Const $FOFX_PREFERHARDLINK = 0x00020000 Global Const $FOFX_SHOWELEVATIONPROMPT = 0x00040000 Global Const $FOFX_EARLYFAILURE = 0x00100000 Global Const $FOFX_PRESERVEFILEEXTENSIONS = 0x00200000 Global Const $FOFX_KEEPNEWERFILE = 0x00400000 Global Const $FOFX_NOCOPYHOOKS = 0x00800000 Global Const $FOFX_NOMINIMIZEBOX = 0x01000000 Global Const $FOFX_MOVEACLSACROSSVOLUMES = 0x02000000 Global Const $FOFX_DONTDISPLAYSOURCEPATH = 0x04000000 Global Const $OFX_DONTDISPLAYDESTPATH = 0x08000000 Global Const $FOFX_RECYCLEONDELETE = 0x00080000 Global Const $FOFX_REQUIREELEVATION = 0x10000000 Global Const $FOFX_COPYASDOWNLOAD = 0x40000000 Global Const $FOFX_DONTDISPLAYLOCATIONS = 0x80000000 Global Const $IID_IShellItem = "{43826d1e-e718-42ee-bc55-a1e261c37bfe}" Global Const $dtag_IShellItem = _ "BindToHandler hresult(ptr;clsid;clsid;ptr*);" & _ "GetParent hresult(ptr*);" & _ "GetDisplayName hresult(int;ptr*);" & _ "GetAttributes hresult(int;int*);" & _ "Compare hresult(ptr;int;int*);" Global Const $IID_IShellItemArray = "{b63ea76d-1f85-456f-a19c-48159efa858b}" Global Const $dtagIShellItemArray = "BindToHandler hresult();GetPropertyStore hresult();" & _ "GetPropertyDescriptionList hresult();GetAttributes hresult();GetCount hresult(dword*);" & _ "GetItemAt hresult();EnumItems hresult();" Global Const $BHID_EnumItems = "{94F60519-2850-4924-AA5A-D15E84868039}" Global Const $IID_IEnumShellItems = "{70629033-e363-4a28-a567-0db78006e6d7}" Global Const $dtagIEnumShellItems = "Next hresult(ulong;ptr*;ulong*);Skip hresult();Reset hresult();Clone hresult();" Global Const $CLSID_IFileOperation = "{3AD05575-8857-4850-9277-11B85BDB8E09}" Global Const $IID_IFileOperation = "{947AAB5F-0A5C-4C13-B4D6-4BF7836FC9F8}" Global Const $dtagIFileOperation = "Advise hresult(ptr;dword*);" & _ "Unadvise hresult(dword);" & _ "SetOperationFlags hresult(dword);" & _ "SetProgressMessage hresult(wstr);" & _ "SetProgressDialog hresult(ptr);" & _ "SetProperties hresult(ptr);" & _ "SetOwnerWindow hresult(hwnd);" & _ "ApplyPropertiesToItem hresult(ptr);" & _ "ApplyPropertiesToItems hresult(ptr);" & _ "RenameItem hresult(ptr;wstr;ptr);" & _ "RenameItems hresult(ptr;wstr);" & _ "MoveItem hresult(ptr;ptr;wstr;ptr);" & _ "MoveItems hresult(ptr;ptr);" & _ "CopyItem hresult(ptr;ptr;wstr;ptr);" & _ "CopyItems hresult(ptr;ptr);" & _ "DeleteItem hresult(ptr;ptr);" & _ "DeleteItems hresult(ptr);" & _ "NewItem hresult(ptr;dword;wstr;wstr;ptr);" & _ "PerformOperations hresult();" & _ "GetAnyOperationsAborted hresult(ptr*);" _Test() Func _Test() Local $sPathFrom = @ScriptDir & "\PathFrom\" Local $sPathTo = @ScriptDir & "\PathTo\" DirRemove($sPathFrom, 1) DirRemove($sPathTo, 1) DirCreate($sPathFrom) For $i = 1 To 5000 FileWrite($sPathFrom & $i & ".txt", "Hello World - " & $i) Next _WinAPI_ShellFileOperation($sPathFrom & "*.*", $sPathTo, $FO_COPY, BitOR($FOF_NOERRORUI, $FOF_NOCONFIRMATION)) ;update file From and To FileWrite($sPathFrom & 1 & ".txt", " Only this should be update in 'To' Folder") FileWrite($sPathTo & 2 & ".txt", " This should not be overwritten but it does :(") MsgBox(0, "ShellFileOperation", "Check these files: " & @CRLF & $sPathFrom & 1 & ".txt" & @CRLF & @CRLF & $sPathTo & 2 & ".txt") _WinAPI_ShellFileOperation($sPathFrom & "*.*", $sPathTo, $FO_COPY, BitOR($FOF_NOERRORUI, $FOF_NOCONFIRMATION)) MsgBox(0, "ShellFileOperation", "Check these files: " & @CRLF & $sPathFrom & 1 & ".txt" & @CRLF & @CRLF & $sPathTo & 2 & ".txt") ;update file From and To FileWrite($sPathFrom & 1 & ".txt", " - I was updated again :-S") FileWrite($sPathTo & 2 & ".txt", " This will not be overwritten :)") MsgBox(0, "IFileOperation", "Check these files: " & @CRLF & $sPathFrom & 1 & ".txt" & @CRLF & @CRLF & $sPathTo & 2 & ".txt") _IFileOperationCopyFiles($sPathFrom, $sPathTo) MsgBox(0, "IFileOperation", "Check these files: " & @CRLF & $sPathFrom & 1 & ".txt" & @CRLF & @CRLF & $sPathTo & 2 & ".txt") DirRemove($sPathFrom, 1) DirRemove($sPathTo, 1) EndFunc ;==>_Test Func _IFileOperationCopyFiles($sPathFrom, $sPathTo, $iFlags = BitOR($FOF_NOERRORUI, $FOFX_KEEPNEWERFILE, $FOFX_NOCOPYHOOKS, $FOF_NOCONFIRMATION)) If Not FileExists($sPathFrom) Then Return SetError(1, 0, False) EndIf If Not FileExists($sPathTo) Then DirCreate($sPathTo) EndIf Local $tIIDIShellItem = CLSIDFromString($IID_IShellItem) Local $tIIDIShellItemArray = CLSIDFromString($IID_IShellItemArray) Local $oIFileOperation = ObjCreateInterface($CLSID_IFileOperation, $IID_IFileOperation, $dtagIFileOperation) If Not IsObj($oIFileOperation) Then Return SetError(2, 0, False) Local $pIShellItemFrom = 0 Local $pIShellItemTo = 0 _SHCreateItemFromParsingName($sPathFrom, 0, DllStructGetPtr($tIIDIShellItem), $pIShellItemFrom) _SHCreateItemFromParsingName($sPathTo, 0, DllStructGetPtr($tIIDIShellItem), $pIShellItemTo) If Not $pIShellItemFrom Or Not $pIShellItemTo Then Return SetError(3, 0, False) Local $oIShellItem = ObjCreateInterface($pIShellItemFrom, $IID_IShellItem, $dtag_IShellItem) Local $pEnum = 0 $oIShellItem.BindToHandler(0, $BHID_EnumItems, $IID_IEnumShellItems, $pEnum) Local $oIEnumShellItems = ObjCreateInterface($pEnum, $IID_IEnumShellItems, $dtagIEnumShellItems) If Not $pEnum Then Return SetError(4, 0, False) $oIFileOperation.SetOperationFlags($iFlags) Local $pItem = 0 Local $iFeched = 0 While $oIEnumShellItems.Next(1, $pItem, $iFeched) = 0 $oIFileOperation.CopyItems($pItem, $pIShellItemTo) WEnd Return $oIFileOperation.PerformOperations() = 0 EndFunc ;==>_IFileOperationCopyFiles Func _SHCreateItemFromParsingName($szPath, $pbc, $riid, ByRef $pv) Local $aRes = DllCall("shell32.dll", "long", "SHCreateItemFromParsingName", "wstr", $szPath, "ptr", $pbc, "ptr", $riid, "ptr*", 0) If @error Then Return SetError(1, 0, @error) $pv = $aRes[4] Return $aRes[0] EndFunc ;==>_SHCreateItemFromParsingName Func CLSIDFromString($sString) Local $tCLSID = DllStructCreate("dword;word;word;byte[8]") Local $aRet = DllCall("Ole32.dll", "long", "CLSIDFromString", "wstr", $sString, "ptr", DllStructGetPtr($tCLSID)) If @error Then Return SetError(1, 0, @error) If $aRet[0] <> 0 Then Return SetError(2, $aRet[0], 0) Return $tCLSID EndFunc ;==>CLSIDFromString Saludos argumentum and Andreik 2 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut 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