Professor_Bernd Posted May 21, 2021 Share Posted May 21, 2021 Goal: All files of a folder should be copied, but existing files should NOT be overwritten. First I tried DirCopy(), but with the flag $FC_NOOVERWRITE no files are copied if the destination folder exists. Then I thought that it must be ok for DirCopy not to overwrite if the destination folder exists. So I tried FileCopy(), also with the $FC_NOOVERWRITE flag, thinking that FileCopy would only not overwrite existing files. But unfortunately it doesn't work! Also FileCopy does not copy anything if the destination folder exists and the flag $FC_NOOVERWRITE is set. In my opinion, with the $FC_NOOVERWRITE flag, FileCopy should only skip existing files, but not abort if the destination folder exists. Here is a minimalistic test code. Before running the code in @TempDir create the folder "MyDocsSource" and in it a few files. The destination folder will be created automatically. #include <FileConstants.au3> ; DirCopy(@TempDir & "\MyDocsSource", @TempDir & "\MyDocsDest", $FC_OVERWRITE) ; <= All files are copied/overwritten. ; DirCopy(@TempDir & "\MyDocsSource", @TempDir & "\MyDocsDest", $FC_NOOVERWRITE) ; <= Nothing is copied if the destination folder exists. ; FileCopy(@TempDir & "\MyDocsSource\*.*", @TempDir & "\MyDocsDest", $FC_OVERWRITE + $FC_CREATEPATH) ; <= All files are copied/overwritten. FileCopy(@TempDir & "\MyDocsSource\", @TempDir & "\MyDocsDest", $FC_CREATEPATH) ; <= Nothing is copied if the destination folder exists. ; Display the temporary directory. ; ShellExecute(@TempDir) How to solve the problem? Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 I just fully tested it from the example file code and it works perfectly. only copies files that don't exist so I don't know what your issue is. #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> Example() Func Example() ; Create a constant variable in Local scope of the filepath that will be read/written to. Local Const $sFilePath = _WinAPI_GetTempFileName(@TempDir) ; Create a temporary file to copy. If Not FileWrite($sFilePath, "This is an example of using FileCopy.") Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the temporary file.") Return False EndIf ; Copy Au3 files in the temporary directory to a new folder/directory called Au3Files. FileCopy(@TempDir & "\*.au3", @TempDir & "\Au3Files\", $FC_NOOVERWRITE + $FC_CREATEPATH) ; Display the temporary directory. ShellExecute(@TempDir) EndFunc ;==>Example 100% works. I even edited the some of the files in the source dir that already existed in the TEMP dir after the initial run to populate the target directory. As expected, FileCopy only copied files that did not exist because my edits were missing from the target dir files that were previously copied there by the initial run of the code. My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 In the example from the help, I don't understand what the temp file is created for. It is not an .au3 file and is not copied. 24 minutes ago, Earthshine said: only copies files that don't exist so I don't know what your issue is. - If the destination folder does NOT exist and I run FileCopy, the destination folder is created and all files from the source folder are copied to the destination folder. - Now the destination folder exists. - Then I add more files in the source folder. - Now when I run FileCopy, NO files are copied. Link to comment Share on other sites More sharing options...
Musashi Posted May 21, 2021 Share Posted May 21, 2021 18 minutes ago, Professor_Bernd said: - Now when I run FileCopy, NO files are copied. This is true (at least for my older AutoIt version 3.3.14.0). The following post by Melba23 explains the problem : https://www.autoitscript.com/forum/topic/176952-filecopy-works-only-with-overwrite-solved/?do=findComment&comment=1270166 Excerpt : Quote If you copy files with a wildcard it will fail if there already are files with the same name and you do not specify that they should be overwritten. As AutoIt just uses the Windows API to do the job, it suffers from the same limitation. Professor_Bernd and water 2 "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 Here is an example that may show the problem better. expandcollapse popup#include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> Example() Func Example() Local $sFilePath ; Creates the source folder. DirCreate(@TempDir & "\MySourceDir\") For $i = 1 to 3 ; Create a variable in Local scope of the filepath that will be read/written to. $sFilePath = _WinAPI_GetTempFileName(@TempDir & "\MySourceDir\") ; Create a temporary file to copy. If Not FileWrite($sFilePath, "This is an example of using FileCopy.") Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the temporary file.") Return False EndIf Next ; Should copy all files from the source folder to the destination folder without overwriting existing files. FileCopy(@TempDir & "\MySourceDir\*.*", @TempDir & "\MyDestDir\", $FC_NOOVERWRITE + $FC_CREATEPATH) ; But it does not do that for me. When I start the script and the destination folder does NOT exist, ; there are 3 files in the source folder and all 3 files are copied to the destination folder. ; ; If I then start the script again and the destination folder now exists, there are 3 files in the source folder ; and NONE are copied to the destination folder. In the destination folder are only the previous 3 files. ; ; Each time I run the script again, there are more files in the source folder, but there are still 3 files ; in the destination folder. ; Display the temporary directory. ShellExecute(@TempDir) EndFunc ;==>Example Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 if there are 3 files in the input directory and they are the same on the second run, then of course no files will be copied. They already exist! Add NEW files to source and try again. My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 15 minutes ago, Musashi said: If you copy files with a wildcard it will fail if there already are files with the same name and you do not specify that they should be overwritten. As AutoIt just uses the Windows API to do the job, it suffers from the same limitation. Oh no! So that means if I copy 1,001 files via wildcards and only one file is already present, the 1,000 not present will NOT be copied. 🤦♂️ Does anyone know another short command I can use with "/AutoIt3ExecuteLine" to copy all files from a source folder that are not present in the destination folder without overwriting? Many thanks to @Musashi for the information! 👍 Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 (edited) 3 minutes ago, Earthshine said: Add NEW files to source and try again. In my code above, 3 new files are created in the source folder with each pass! Edited May 21, 2021 by Professor_Bernd Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 I just tested your code and it works, although it makes .tmp files in the destination dir. not sure why but the filecopy works. My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 (edited) why on earth are you looping? and using *.* includes .TMP files that must get created with FileCopy. use wildcards like this *.txt *.au3, etc.. this code is not needed at ALL For $i = 1 to 3 ; Create a variable in Local scope of the filepath that will be read/written to. $sFilePath = _WinAPI_GetTempFileName(@TempDir & "\MySourceDir\") ; Create a temporary file to copy. If Not FileWrite($sFilePath, "This is an example of using FileCopy.") Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the temporary file.") Return False EndIf Next take that out of there no need to create the source dir 3 TIMES! Edited May 21, 2021 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 Hmm, what's different about it that makes it work for you? What can I do to make it work for me too? @Musashi Can you or someone else also test the code and tell what happens? Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 here is your code I modified and it works, but it includes a TMP file that gets created when run. I think it's because you use *.* anyway, try this. #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> Example() Func Example() Local $sFilePath ; Creates the source folder. ; Create a variable in Local scope of the filepath that will be read/written to. $sFilePath = _WinAPI_GetTempFileName(@TempDir & "\MySourceDir\") ; Should copy all files from the source folder to the destination folder without overwriting existing files. FileCopy(@TempDir & "\MySourceDir\*.*", @TempDir & "\MyDestDir\", $FC_NOOVERWRITE + $FC_CREATEPATH) ; Display the temporary directory. ShellExecute(@TempDir) EndFunc ;==>Example My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Musashi Posted May 21, 2021 Share Posted May 21, 2021 One way to copy files, but not overwrite existing files in the destination folder : Local $hSearch, $sSourceDir, $sDestinationDir, $sFileName $sSourceDir = @ScriptDir & "\Source\" $sDestinationDir = @ScriptDir & "\Destination\" $hSearch = FileFindFirstFile($sSourceDir & "*.*") ; Check, if Destination folder exists. If not, then create it : If Not StringInStr(FileGetAttrib($sDestinationDir), "D") Then DirCreate($sDestinationDir) While True $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop If (Not FileExists($sDestinationDir & $sFileName)) And (Not StringInStr(FileGetAttrib($sSourceDir & $sFileName), "D")) Then FileCopy($sSourceDir & $sFileName, $sDestinationDir) EndIf WEnd FileClose($hSearch) Earthshine 1 "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 nice job @Musashi Musashi 1 My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Musashi Posted May 21, 2021 Share Posted May 21, 2021 I also tried : #include <WinAPIShellEx.au3> _WinAPI_ShellFileOperation (@ScriptDir & "\Source\*.*", @ScriptDir & "\Destination\", $FO_COPY, BitOR($FOF_SILENT, $FOF_NOCONFIRMATION)) ConsoleWrite("Error=" & @error & " Extended=" & @extended & @CRLF) ; *** just a message but there doesn't seem to be a flag for "not overwrite existing files" "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 (edited) Ok, I modified the sample code again. The #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> Example() Func Example() Local $sFilePath ; Creates the source folder. ; Should copy all files from the source folder to the destination folder without overwriting existing files. FileCopy(@TempDir & "\MySourceDir\*.*", @TempDir & "\MyDestDir\", $FC_NOOVERWRITE + $FC_CREATEPATH) ; Display the temporary directory. ShellExecute(@TempDir) EndFunc ;==>Example the line of code $sFilePath = _WinAPI_GetTempFileName(@TempDir & "\MySourceDir\") you DO NOT NEED!!! it creates a temp file and was used in the example just to create a file to copy. DO NOT USE THAT FUNCTION and you will not get .TMP files in your dest directory Edited May 21, 2021 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 4 minutes ago, Earthshine said: why on earth are you looping? Please excuse me, but I don't understand what you want. In the loop I create 3 temp files. In each pass a temp name is created and then the temp file. 3 passes = 3 temp files. 6 minutes ago, Earthshine said: take that out of there no need to create the source dir 3 TIMES! Where do you see that the source folder is created 3x? There are 3 temp files created, no folder! 12 minutes ago, Earthshine said: why on earth are you looping? and using *.* includes .TMP files that must get created with FileCopy. use wildcards like this *.txt *.au3, etc.. How else can you copy all the files? Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 (edited) I was testing using real .au3 files. not using temp files. See my last post with the proper code for your example that does work perfectly I just create that dir in TEMP and put 3 files in it. run the example, note the output dir has those three files. add two more files to source dir. edit the other three that were there so that they are different from what was copied in run 1. that way you can test the output files to make sure they are not overwritten. I think you confuse yourself alot of the times. oh and ALL the files are copied by the single FileCopy statement. that is how to copy ALL files. Edited May 21, 2021 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Professor_Bernd Posted May 21, 2021 Author Share Posted May 21, 2021 19 minutes ago, Earthshine said: take that out of there no need to create the source dir 3 TIMES! From the help file: $FC_CREATEPATH (8) = Create destination directory structure if it doesn't exist Link to comment Share on other sites More sharing options...
Earthshine Posted May 21, 2021 Share Posted May 21, 2021 1 minute ago, Professor_Bernd said: From the help file: $FC_CREATEPATH (8) = Create destination directory structure if it doesn't exist just get it out of there. use the code i posted above and test it. If you don't want to do that then I am done. Later. My resources are limited. You must ask the right questions 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