Posts: 14
Threads: 4
Joined: May 2008
I am writting a simple backup script for a few users. I need to know if when using COP there is a flag I can use so that when copying the files can I set it to "ignore" files that already exist at the destination?
Posts: 12,147
Threads: 143
Joined: Dec 2002
No, cop does not have such flag.
Posts: 12,147
Threads: 143
Joined: Dec 2002
Function BackupFiles
;/
function $source $destFolder [ifExists] [flags] ;;ifExists - 0 replace, 1 dialog, 2 rename, 3 error, 4 do nothing, 5 replace if source is newer; flags: 1 no intermediate folder
;Copies files to a folder.
;Error if fails to copy a file.
;source - file, folder or list of files and/or folders. Also can be drive(s). Error if does not exist.
;destFolder - destination folder. The function creates it if does not exist.
ARRAY(str) aS aD
GetFileCopyPaths source destFolder aS aD flags
str sS(aS) sD(aD)
;out "---- src ----[]%s[]---- dest ----[]%s" sS sD
sel ifExists
,case 0
,cop- sS sD
,
,case 1
,cop sS sD
,
,case 2
,cop+ sS sD
,
,case [3,4,5]
,int i
,for i aD.len-1 -1 -1
,,if(!dir(aD[i])) continue
,,sel ifExists
,,,case 3
,,,end "Destination file '%s' already exists" 0 aD[i]
,,,
,,,case 5
,,,long d1 d2
,,,memcpy &d2 &_dir.fd.ftLastWriteTime 8
,,,dir aS[i]
,,,memcpy &d1 &_dir.fd.ftLastWriteTime 8
,,,if(d1>d2) continue
,,
,,aD.remove(i)
,,aS.remove(i)
,,
,sS=aS; sD=aD
,;out "---- src ----[]%s[]---- dest ----[]%s" sS sD
,if(aD.len) cop- sS sD
,
,case else end ES_BADARG
err+ end _error
Function GetFileCopyPaths
;/
function $source $destFolder ARRAY(str)&aSources ARRAY(str)&aDestinations [flags] ;;flags: 1 no intermediate folder
;Gets paths of all source and destination files to be used in a copy operation.
;source - file, folder or list of files and/or folders. Also can be drive(s). Error if does not exist.
;destFolder - destination folder.
;aSources - receives full paths of all files (but not folders) to be copied.
;aDestinations - receives full paths of all files (but not folders) that would be created in destFolder after a copy opertion.
aSources=0; aDestinations=0
str sListS sListD sDF sDF2 s1 s2
sDF.expandpath(destFolder); sDF.rtrim("\")
foreach s1 source
,s2.expandpath(s1); s2.rtrim("\")
,if(!dir(s2 2)) end "source not found"
,
,if _dir.fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY
,,if flags&1
,,,sDF2=sDF
,,else
,,,int i=findcr(s2 '\')
,,,if(i>0) sDF2.from(sDF s2+i)
,,,else sDF2.from(sDF "\" _s.left(s2 1)) ;;E:
,,
,,Dir d
,,foreach(d _s.from(s2 "\*") FE_Dir 0x4)
,,,str sPath=d.FileName(1)
,,,aSources[]=sPath
,,,aDestinations[].from(sDF2 sPath+s2.len)
,else
,,aSources[]=s2
,,aDestinations[].from(sDF s2+findcr(s2 '\'))
Posts: 14
Threads: 4
Joined: May 2008
I have pasted the "meat" of my script below. After reading your comment, I tried a few things but couldn't get it to gel. How would I use your "case 5" scenerio here?
cop- "$documents$" "Y:\backup"
cop- "$desktop$" "Y:\backup"
cop- "$favorites$" "Y:\backup"
--------------------your script --------------------------
"function $source $destFolder [ifExists] [flags] ;;ifExists - 0 replace, 1 dialog, 2 rename, 3 error, 4 do nothing, 5 replace if source is newer; flags: 1 no intermediate folder"
Posts: 12,147
Threads: 143
Joined: Dec 2002
BackupFiles "$documents$" "Y:\backup" 5
Posts: 14
Threads: 4
Joined: May 2008
OK, I am bugging you, but my QM doesn't appear to understand "backups"
Posts: 12,147
Threads: 143
Joined: Dec 2002
Where in your code is "backups"? And what QM says?
Create 2 new functions, named BackupFiles and GetFileCopyPaths. Paste the codes from my other post.
Then create new macro and paste
BackupFiles "$documents$" "Y:\backup" 5
Posts: 14
Threads: 4
Joined: May 2008
Whoops... I meant...
BackupFiles "$documents$" "Y:\backup" 5
I replaced cp- with BackupFiles...
Posts: 12,147
Threads: 143
Joined: Dec 2002
Create 2 new functions, named BackupFiles and GetFileCopyPaths. Paste the codes from my other post.
Then create new macro and paste
BackupFiles "$documents$" "Y:\backup" 5
Posts: 14
Threads: 4
Joined: May 2008
IT WORKS!!!!
You thwe man  Thanks as always..
Posts: 15
Threads: 3
Joined: Sep 2006
Hi!
I want to ask something about cop command and flags.
I'm having trouble when using flags for this command. I don't know what I'm doing wrong.
,a.format("%s%s" Path1 F1)
,b.format("%s%s" Path2 F1)
,out "Cop %s %s" a b
,;;;Cop D:\Documents and Settings\IzK\Desktop\1234\F\QP\File.qpw D:\Documents and Settings\IzK\Desktop\1234\B\QP\File.qpw
,cop a b FOF_SILENT|FOF_NOCONFIRMMKDIR|FOF_FILESONLY
I need to use the flags: FOF_SILENT, FOF_NOCONFIRMMKDIR, FOF_FILESONLY, but ever crashes. I have tried to use 644 and 0x284 as flag, but crashes too. 
I don't know what to do. In the code, the comment is the output from previous order.
The only diference between source and destination is marked in bold (I show the end of string):
\ B\QP\File.qpw
I hope you can help me.
And sorry for my bad english.
Thanks.
IzK
Posts: 12,147
Threads: 143
Joined: Dec 2002
How it crashes?
Everything is correct and should work. Works on my computer. I use QM 2.3.2.
Macro Macro1423
cop "$desktop$\test.txt" "$desktop$\A\B\C\test.txt" FOF_SILENT|FOF_NOCONFIRMMKDIR|FOF_FILESONLY
Posts: 15
Threads: 3
Joined: Sep 2006
It gives me the same error....
Sorry for no explaining enough in my first post.
The error is:
Error (RT) in SB_Copy: cannot copy file
I have done some tests again.
The order works... but when destination folder doesn't exists, gives the error above.(only when used with the other flags).
If I do a 'cop a b FOF_NOCONFIRMMKDIR' without any other flag works fine (slow, but works)
It's a bit strange......
I'm using QM 2.2.1.5 :-(
I'll look up a bit more..... Thanks.
EDIT: Here is the code of the function SB_Copy.
At the end, where is the copy of the file, I have putted 3 "modes". Obviously, I have run the macro with two of them commented.
In comments, are the results: Times (sum of all, and divided by 6), filesize, the same. The smallest was 1615K and the biggest 2310K.
function ~F1 ~Path1 ~Path2 #Num [#Version]
;;;F1 = Filename with relative path
;;;Path1 = Source
;;;Path2 = Destination
;;;Num = Max.Versions available
;;;Version = Current version. for recursivity
if(!Version) Version=0
str name = SB_getVersionName(F1 Path2 Version 2)
str a b
Dir d
if (d.dir(name)) ;; name exists.
,if (Version < Num)
,,SB_Copy(F1 Path1 Path2 Num (Version+1))
,else
,,;del- name
,,out "Delete %s" name
if (Version>0)
,a = SB_getVersionName(F1 Path2 (Version-1) 2)
,b = name
,;out "Ren %s %s" a b
,ren a b FOF_SILENT
if(Version=0)
,a.format("%s%s" Path1 F1)
,b.format("%s%s" Path2 F1)
,out "Cop %s %s" a b
,
,;MODE 1: (WORKS)
,long perf1 = perf
,cop a b FOF_NOCONFIRMMKDIR
,;perf says about 1000589 for each file. There was 6 files of 1765KB each one
,long perf2 = perf
,out (perf2-perf1)
,;MODE 2: (WORKS only if destination folder exists. Obvious)
,long perf1 = perf
,cop a b FOF_SILENT|FOF_FILESONLY
,;perf says about 25943 for each file. There was 6 files of 1765KB each one
,long perf2 = perf
,out (perf2-perf1)
,;MODE 2: (WORKS like Mode 2. If not exist, crashes)
,long perf1 = perf
,cop a b FOF_NOCONFIRMMKDIR|FOF_SILENT|FOF_FILESONLY
,;perf says about 23108 for each file. There was 6 files of 1765KB each one
,long perf2 = perf
,out (perf2-perf1)
ret
Posts: 15
Threads: 3
Joined: Sep 2006
Well, I have solved the problem....
I have tried my macro on another computer, with version 2.2.1.5 too, and don't work.
Then, in this second computer, I have installed the newest version, 2.3.x (I don't remember :roll: ), and the result was the same:
"Can't copy file".
The only solution I have found is create the folder before copying the file. And so looks it:
,mkdir _s.getpath(b)
,cop a b FOF_NOCONFIRMMKDIR|FOF_SILENT
maybe it's not so nice, but works.
Thanks for your tiem, Gintaras  (And for your app too!)
Posts: 12,147
Threads: 143
Joined: Dec 2002
It is Windows bug or strange undocumented behavior.
cop uses Windows API function SHFileOperation.
On XP, it fails if flags FOF_SILENT and FOF_NOCONFIRMMKDIR are used together. Works well on Windows 7.
But succeeds if SHFILEOPSTRUCT.hwnd is nonzero. I'll add it in next QM.
Macro Macro1423
str a="$desktop$\1234\A\QP\test.txt"
str b="$desktop$\1234\B\QP\test.txt"
;for testing:
;create a
mkdir "$desktop$\1234\A\QP"
_s.all(5*1024*1024 2 '.')
_s.setfile(a)
;also delete B
del- "$desktop$\1234\B"; err
;mkdir "$desktop$\1234\B\QP"
int t1=perf
;cop a b FOF_SILENT|FOF_NOCONFIRMMKDIR
;cop a b FOF_NOCONFIRMMKDIR
;cop a b
a.expandpath; a.fromn(a -1 "" 1)
b.expandpath; b.fromn(b -1 "" 1)
SHFILEOPSTRUCTW x
x.hwnd=GetDesktopWindow
x.wFunc=FO_COPY
x.pFrom=@a
x.pTo=@b
;x.fFlags=FOF_NOCONFIRMMKDIR
x.fFlags=FOF_SILENT|FOF_NOCONFIRMMKDIR
int e=SHFileOperationW(&x)
if(e) out _s.dllerror("Error: " "" e)
int t2=perf
out t2-t1
This code succeeds because of x.hwnd=GetDesktopWindow. QM currently uses x.hwnd=0.
|