- NSIS Discussion
- Need help w/ files copy (loop?)
Archive: Need help w/ files copy (loop?)
Jnuw
20th November 2004 00:50 UTC
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.
Erpo
20th November 2004 04:55 UTC
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
Takhir
20th November 2004 07:55 UTC
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
Afrow UK
20th November 2004 09:04 UTC
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
Takhir
20th November 2004 09:45 UTC
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?
Jnuw
20th November 2004 19:02 UTC
Thanks everyone, Takhir's code is working perfectly. You all rock!
Jnuw
23rd November 2004 16:11 UTC
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.
pengyou
23rd November 2004 17:00 UTC
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.
Jnuw
23rd November 2004 17:13 UTC
Thanks pengyou, I didn't see that because I was "editing" my post, but I see it now on a new reply.
Afrow UK
23rd November 2004 18:12 UTC
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
Jnuw
23rd November 2004 18:18 UTC
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.
Takhir
23rd November 2004 18:32 UTC
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?
Afrow UK
23rd November 2004 18:32 UTC
If that doesn't fix the problem then it must be either an internal problem with NSIS or with Windows itself.
-Stu
Jnuw
23rd November 2004 22:18 UTC
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!
Takhir
24th November 2004 07:07 UTC
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).