Archive: Need help w/ files copy (loop?)


Need help w/ files copy (loop?)
  Hello all. What I need to do is copy a bunch of *.mdb files out of an unknown number of folders of which I do not know the name of (I know what your saying, this sounds fun already!). I tried the following, and it did not work, but I think it will give you the idea of what I’m trying to do.

CopyFiles "c:\source\*\*.mdb" "C:\destination\"

The first * in the above line is my problem. I don't know the name of the folders in the "source" directory, and I don't know how many there are. I only know there is 1 .mdb file in each folder.

I don't know much about push, pop, and the stack, but it seems to me a loop could first be set up to read in (push) in each of the folder names in the "source" directory into the stack. Then a second loop could run that would pop the stack 1 at a time to set the $0 variable. The CopyFiles command would run after each pop, until the stack was empty, like this.

CopyFiles "c:\source\$0\*.mdb" "C:\destination\"

Would this work? Any help, or code examples would be great. Thanks all.


CopyFiles "c:\source\*\*.mdb" "C:\destination\"
I think no matter how you eventually get it to work, the above is going to be the most intuitive syntax for accomplishing your task. Maybe, if you ask nicely, the developers will add support for multiple wildcards.


For now, here's something that might work. I'm not sure if the "C:\source\*.*" part will match directories in C:\source\ as well as files, but if it's consistent with the rest of the scripting language it should (e.g. File /r "C:\source\*.*").

Push $0
Push $1
FindFirst $0 $1 "C:\source\*.*"
loop:
StrCmp $1 "" done
CopyFiles "$1\*.mdb" "C:\destination\"
FindNext $0 $1
Goto loop
done:
Pop $1
Pop $0

Some remarks :)
First of all we are talking about files copy on user's comp (CopyFiles parameter is filespec_on_destsys).
Pop and Push are optional - if you want to save vars content.
Folder names may not inclide ".", so original syntax "*" looks better for me then "*.*"
FindFirst/Next also finds "." and ".."
If your source folder may include files, you need to check that name is directory, not file.
This works but with pauses, may be I forgot something :) ?

Section "Dummy Section" SecDummy

CreateDirectory "$INSTDIR"
FindFirst $0 $1 "$EXEDIR\*"
loop:
;MessageBox MB_OK "All files $1"
StrCmp $1 "" done
IfFileExists "$1\*" 0 +4
StrCmp $2 ".." +3
StrCmp $2 "." +2
CopyFiles /FILESONLY "$1\*.mdb" "$INSTDIR"
FindNext $0 $1
Goto loop
done:

sectionend


You missed FindClose $0 at the end. It's always a good idea to use Push and Pop's no matter how small the code may be. Otherwise new people tend to wonder why their variable datas have changed.

-Stu


FindClose is a good idea :) , and $1 in StrCmp, not $2, but I still see 1-2 second pauses on Win98 SE between 2 MessageBoxes

Section "Dummy Section" SecDummy

CreateDirectory "$INSTDIR"
FindFirst $0 $1 "$EXEDIR\*"
loop:
StrCmp $1 "" done
IfFileExists "$1\*" 0 fndnxt
StrCmp $1 ".." fndnxt
StrCmp $1 "." fndnxt
MessageBox MB_OK "Dir exists $1"
CopyFiles /FILESONLY "$1\*.mdb" "$INSTDIR"
MessageBox MB_OK "After CopyFiles"
fndnxt:
FindNext $0 $1
Goto loop
done:
FindClose $0

sectionend

This not happens on WinXP Pro. Who knows whY? System bug?


Thanks everyone, Takhir's code is working perfectly. You all rock!


Hey guys, I was wondering if someone could check this for a bug. The code below is working perfectly, however on my Win2K Pro workstation, I get the 3-4 second pause during execution as Takhir was talking about. I get no pause at home on my XP Pro PC. I have isolated the pause to the "CopyFiles" line. I put a message box before and after that line, that’s where the pause is. It seems there is about a 1 second pause each time that line is hit, so for a loop of 70 folders, that’s a really long pause. Any help would be most appreciated.


OutFile CollectMDBs.exe

AutoCloseWindow True

>Var SourceFolder
>Var DestFolder

Section ""

ReadINIStr $SourceFolder $EXEDIRCollect.ini Source SourceFolder
ReadINIStr $DestFolder $EXEDIRCollect
.ini Destination DestFolder

FindFirst$0 $1 "$SourceFolder\*"
loop:
StrCmp $1 "" done
IfFileExists"$SourceFolder\$1\*" 0 fndnxt
StrCmp$1 ".." fndnxt
StrCmp$1 "." fndnxt
CopyFiles/FILESONLY "$SourceFolder\$1\*.mdb" "$DestFolder"
fndnxt:
FindNext $0 $1
Goto loop
done:
FindClose $0

sectionend
>
p.s. Click HERE to download a Zip file with a sample directory structure to test this code, thanks.

p.p.s If someone can tell me how to put an attachment on this post, that would be great, i could not see how.

If you click the "Post a reply" button you'll get a page which lets you enter your message and attach a file to it.


Thanks pengyou, I didn't see that because I was "editing" my post, but I see it now on a new reply.


Have you checked that the $DestFolder exists already?
You should also use IfErrors to check when FindNext has finished:

IfFileExists "$DestFolder\*" +2
CreateDirectory $DestFolder

ClearErrors
FindFirst $0 $1 "$SourceFolder\*"
IfErrors done
loop:
IfFileExists "$SourceFolder\$1\*" 0 fndnxt
StrCmp $1 ".." fndnxt
StrCmp $1 "." fndnxt
CopyFiles /FILESONLY "$SourceFolder\$1*.rmf" "$DestFolder"
fndnxt:
ClearErrors
FindNext $0 $1
IfErrors 0 loop
done:
FindClose $0
-Stu

Afrow UK, thanks for the suggestion. Yes, the $DestFolder does exist. And that’s good to know about the IfErrors, but does anyone know about the strange delay? Thanks.


This is system bug, C code below shows 1006 - 1020 ms delay on my comp under Win98 (with or without dir, files exist or not..) It's SHFileOperation().

op.fFlags=FOF_FILESONLY|FOF_NOCONFIRMATION ;
t1 = GetTickCount();
res=SHFileOperation(&op);
sprintf(buf2, "time %d ms, res %d", GetTickCount() - t1, res);
MessageBox(NULL, buf2, "Time", 0);

exec.c NSIS file, SHFileOperation - what instead?


If that doesn't fix the problem then it must be either an internal problem with NSIS or with Windows itself.

-Stu


Takhir, your last post was a bit over my head, I’m not sure I understand. So is there anything I can do about the delay or no? Thanks!


Jnuw, looking from my corner situation is following: MS forgot Sleep(1 sec) in the SHFileOperation API call (Win98 and Win2K, not WinXP). I see 3 ways:
1) try to create second findfile-filecopy loop for mdb files and do copy using NSIS CopyFiles (for single file - not tested) or using System plug-in and CopyFile() API call.
2) Wait a little - may be NSIS developers can do something with this in exec.c file (current version or 2.03?).
3) write a plug-in (C program).