Skip to content
⌘ NSIS Forum Archive

CopyFiles *.dll with subfolders

6 posts

r2du-soft#

CopyFiles *.dll with subfolders

hi i have a problem with CopyFiles
when i use from this code:

CreateDirectory "C:\DLLFiles\"
CopyFiles "C:\Program Files\R2duApplication\*.DLL"  "C:\DLLFiles\" 
application copy all DLL files in Main folder but cant copy Sub folder Dll...

CopyFiles haven't a switch for sub folders?

for example in command line xcopy have parameter /s for sub folders...

and i do not want use from file /r ,i just want copy dll files in main folder and sub folders...
Anders#
NSIS just uses the SHFileOperation Windows function and that seems to act a little strange. The wildcard applies to files and folders in the root directory but does not even apply to files in subdirectories!

Section
CreateDirectory "$Temp\TestInst\Src\SubDir"
CreateDirectory "$Temp\TestInst\Src\SubDir.dll"
File "/oname=$Temp\TestInst\Src\a.dll" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\b.exe" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\c" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir\a.dll" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir\b.exe" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir\c" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir.dll\a.dll" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir.dll\b.exe" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir.dll\c" "${__FILE__}"
CopyFiles "$Temp\TestInst\Src\*.dll" "$Temp\TestInst\Dst"
SectionEnd
Anders#
You could use ${Locate} or FindFirst to copy each subdirectory but that would result in several copy dialogs.

Here is some code that tries to do it all in one operation:

!if 0n1 > 0 ; >= v3.0b0
!include LogicLib.nsh
!include Util.nsh
!ifdef DEBUG
Function SHFileOp_Dump
System::Store S
Pop $0
loop:
System::Call kernel32::lstrlen(t)(pr0)i.r1
System::Call *$0(&t$1.r2,&i${NSIS_CHAR_SIZE}.r3,&i${NSIS_CHAR_SIZE}.r4)
DetailPrint $2(len=$1|$3,$4)
IntOp $1 $1 + 1
IntOp $1 $1 * ${NSIS_CHAR_SIZE}
${IntPtrOp} $0 $0 + $1
IntCmp $4 0 "" loop loop
System::Store L
FunctionEnd
!endif
!macro SHFileOp_Initialize shfo_outvar
System::Call *(p0,p0,p0,p0,p0,p0,p,p)p.s
Pop ${shfo_outvar}
!macroend
!macro SHFileOp_Append shfo src dst result_outvar
Push "${dst}"
Push "${src}"
Push ${shfo}
Call SHFileOp_Append
Pop ${result_outvar}
!macroend
!macro SHFileOp_Append_Internal sys1 sys2 shfo
Pop $1
StrLen $2 $1
Push $2
System::Call *${shfo}(${sys1}p.r3${sys2}.r5)
IntOp $2 $2 + 1 ; '\0'
!if "${NSIS_CHAR_SIZE}" > 1
IntOp $2 $2 * ${NSIS_CHAR_SIZE}
!endif
IntOp $6 $3 + $2
IntOp $6 $6 + ${NSIS_CHAR_SIZE} ; 2nd '\0'
System::Alloc $6
Pop $7
${If} $7 P<> 0
${If} $3 <> 0
System::Copy /$3 $7 $5
System::Free $5
IntOp $3 $3 - ${NSIS_CHAR_SIZE}
IntOp $6 $6 - ${NSIS_CHAR_SIZE}
${EndIf}
Pop $2
System::Call '*$7(&i$3,&t$2r1,&i${NSIS_CHAR_SIZE} 0,&i${NSIS_CHAR_SIZE} 0)'
System::Call *${shfo}(${sys1}pr6${sys2}$7)
${EndIf}
!macroend
Function SHFileOp_Append
System::Store S
Pop $0
!insertmacro SHFileOp_Append_Internal "" ",p,p" $0
${If} $7 P<> 0
!insertmacro SHFileOp_Append_Internal "p," ",p,p" $0
${EndIf}
Push $7
System::Store L
FunctionEnd
!macro SHFileOp_Perform shfo op flags title result_outvar
Push $1
Push $2
System::Call '*${shfo}(p$hwndparent,p${op},p.r1,p.r2,i${flags}|1,i,p,ts)' "${title}"
!ifdef DEBUG
System::Call '*${shfo}(p.R1,p.R2,p.R3,p.R4,i.R5,i.R6,p.R7,p.R8)'
DetailPrint 1=$R1==$hwndparent(shfo=${shfo})
DetailPrint 2=$R2=func
DetailPrint 3=$R3=src
DetailPrint 4=$R4=dst
DetailPrint 5=$R5=flags
DetailPrint 6=$R6=dontcare
DetailPrint 7=$R7=dontcare
DetailPrint 8=$R8==title
Push $R3
Call SHFileOp_Dump
Push $R4
Call SHFileOp_Dump
!endif
System::Call 'SHELL32::SHFileOperation(t)(p${shfo})i.s'
System::Free ${shfo}
System::Free $1
System::Free $2
Exch 2
Pop $2
Pop $1
Pop ${result_outvar}
!macroend
!endif

Section
CreateDirectory "$Temp\TestInst\Src\SubDir"
CreateDirectory "$Temp\TestInst\Src\SubDir.dll"
File "/oname=$Temp\TestInst\Src\a.dll" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\b.exe" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\c" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir\a.dll" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir\b.exe" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir\c" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir.dll\a.dll" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir.dll\b.exe" "${__FILE__}"
File "/oname=$Temp\TestInst\Src\SubDir.dll\c" "${__FILE__}"

!define FO_COPY 2
!define FOF_NOCONFIRMATION 0x0010
!define FOF_FILESONLY 0x0080
!define FOF_SIMPLEPROGRESS 0x0100
!define FOF_NOCONFIRMMKDIR 0x0200
!define FOF_NOERRORUI 0x0400
!define FOF_NORECURSION 0x1000 ; Does not work?
!insertmacro SHFileOp_Initialize $9
!insertmacro SHFileOp_Append $9 "$Temp\TestInst\Src\*.dll" "$Temp\TestInst\Dst" $0
!insertmacro SHFileOp_Append $9 "$Temp\TestInst\Src\SubDir\*.dll" "$Temp\TestInst\Dst\SubDir" $0
!insertmacro SHFileOp_Append $9 "$Temp\TestInst\Src\SubDir.dll\*.dll" "$Temp\TestInst\Dst\SubDir.dll" $0
!insertmacro SHFileOp_Perform $9 ${FO_COPY} "${FOF_NOCONFIRMATION}|${FOF_NOCONFIRMMKDIR}|${FOF_NORECURSION}|${FOF_NOERRORUI}|${FOF_SIMPLEPROGRESS}|${FOF_FILESONLY}" "Copying something" $0
DetailPrint Error=$0
SectionEnd
r2du-soft#
Originally Posted by Yathosho View Post
You can easily modify one of the examples for the Locate header

Thanks Mr Yathosho

Originally Posted by Anders View Post
You could use ${Locate} or FindFirst to copy each subdirectory but that would result in several copy dialogs.

Here is some code that tries to do it all in one operation:


(Not tested as 64-bit, might not work there...)


Thanks Mr Anders

i test your code,i have 64-bit windows and code application not run and show me error debug!

i need a easy code (no long) short with CopyFiles...

i write this code for sample:


Section
;-------------------
CreateDirectory "$Temp\Test\AllFiles\"
;-------------------
File "/oname=$Temp\Test\AllFiles\A.0.dll" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\A.1.dll" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\A.2.exe" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\A.3.dat" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\A.4.mp3" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\A.5.mp4" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\A.6.mkv" "${__FILE__}"
;-------------------
;-------------------
CreateDirectory "$Temp\Test\AllFiles\Sub1"
;-------------------
File "/oname=$Temp\Test\AllFiles\Sub1\B.0.dll" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub1\B.1.dll" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub1\B.2.exe" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub1\B.3.dat" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub1\B.4.mp3" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub1\B.5.mp4" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub1\B.6.mkv" "${__FILE__}"
;-------------------
;-------------------
CreateDirectory "$Temp\Test\AllFiles\Sub2"
;-------------------
File "/oname=$Temp\Test\AllFiles\Sub2\C.0.dll" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub2\C.1.dll" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub2\C.2.exe" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub2\C.3.dat" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub2\C.4.mp3" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub2\C.5.mp4" "${__FILE__}"
File "/oname=$Temp\Test\AllFiles\Sub2\C.6.mkv" "${__FILE__}"
;-------------------
CreateDirectory "$Temp\Test\Just.DLLFiles\"
CopyFiles "$Temp\Test\AllFiles\*.DLL" "$Temp\Test\Just.DLLFiles\"  
SectionEnd 



after create files i copy .dll file from directory AllFiles to directory Just.DLLFiles with CopyFiles code,but CopyFiles just copy main folder dll (A.0.dll and A.1.dll) but i need a code for copy dll from main folder and sub folders dll files (A.0.dll,A.1.dll,B.0.dll,B.1.dll,C.0.dll,C.1.dll)

in finally:

Copy Dll file from Directory AllFiles To Directory Just.DLLFiles (A.0.dll and A.1.dll)
Copy Dll file from Directory AllFiles\Sub1 To Directory Just.DLLFiles\Sub1 (B.0.dll,B.1.dll)
Copy Dll file from Directory AllFiles\Sub2 To Directory Just.DLLFiles\Sub2 (C.0.dll,C.1.dll)
Anders#
And we already told you, CopyFiles cannot do this, you need to use ${Locate} and call CopyFiles multiple times.

I think I fixed my example, you can try that again...