Well, the purpose of this header was originally for U3 launchers so I could delegate cleanup functions to a separate executable from the launcher, but perhaps it can be useful, so I thought I'd share here. For example, if you are performing cleanup functions from within the launcher (as per PAF), the AddFilesToCopy function is practically useless, as it just passes its parameters to CopyFiles, so it's redundant. However, in the separate appstop scenario for U3, this makes sense, so you can specify the files to be copied from the launcher and then do the copying from an appstop executable that uses this header, and then you don't have to code any files/paths into the appstop, just call FileCleanup. Basically what happens is that when you call any of the AddSomethingToDoSomething functions, it compiles a list of files and folders and what to do with each. Then, when you call FileCleanup, it executes your instructions on all of the files in the list. Currently a work in progress, so comments and constructive criticisms are welcome. I eventually want to do basically the same sort of thing with registry edits, but we'll see.
${AddFileToKeep} FILE
FILE will be kept upon calling FileCleanup
${AddFolderToKeep} FOLDER
FOLDER will be kept upon calling FileCleanup
${AddFileToRemove} FILE
FILE will be deleted upon calling FileCleanup
${AddFolderToRemove} FOLDER
FOLDER will be deleted upon calling FileCleanup
${AddFilesToCopy} COPYFROM COPYTO
COPYFROM will be copied to COPYTO upon calling FileCleanup. COPYTO can be a file or a folder. Files/folders in this list will simply be run through NSIS's CopyFiles command, so treat it exactly the same.
${FileCleanup}
-Copies all files/folders in the Copy list
-Removes all files/folders in the Remove list
-Backs up all files/folders in the Keep list
-Empties parent directories of all files/folders in the Keep list
(This is why you DON'T call AddFileToKeep on files in, say a root directory!)
-Returns all files/folders in the Keep list to their original directories.
;FileCleanup.nsh
;Copyright 2009 qwertymodo
;Creates a list of files/folders to keep or remove
;at cleanup time. Any file/folder that is set to
;be removed will simply be deleted when ${CleanUp}
;is called. Any file/folder that is set to be
;"kept" will remain, while THE REST of the contents
;of its parent folder will be removed
;****************W*A*R*N*I*N*G*!****************;
;WHEN YOU CALL ${KeepFile} OR ${KeepFolder}, ALL
;CONTENTS OF THE PARENT FOLDER NOT "KEPT" WILL BE
;DELETED!! NEVER CALL EITHER OF THESE FUNCTIONS
;ON A FILE LOCATED AT THE ROOT OF A DRIVE OR IN A
;SYSTEM FOLDER! SYSTEM POLICY SHOULD BLOCK ANY
;ATTEMPTS TO DO SO, BUT DON'T TRY IT!
;***********************************************;
;NOTE: Always use fully qualified paths
!include FileFunc.nsh
!insertmacro GetParent
!insertmacro GetFileName
Function AddToCleanupList
;===Get file name
Exch $1 ;keep or remove
Exch
Exch $2 ;file or folder
Exch 2
Exch $9 ;file/folder name
Push $0
;===Check for valid file
IfFileExists $9 "" Done
;===Check for existing list
IfFileExists "$EXEDIR\FileCleanup.ini" +3
GetTempFileName $0 $EXEDIR
Rename $0 "$EXEDIR\FileCleanup.ini"
;===Add file
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "$1" "NumberOf$2s"
IfErrors 0 +3
ClearErrors
StrCpy $0 0
IntOp $0 $0 + 1
WriteINIStr "$EXEDIR\FileCleanup.ini" "$1" "NumberOf$2s" $0
WriteINIStr "$EXEDIR\FileCleanup.ini" "$1" "$2$0" "$9"
;===Put the stack back
Done:
Pop $0
Pop $9
Pop $1
Pop $2
FunctionEnd
Function AddToCopyList
Exch $1 ;copy from
Exch
Exch $2 ;copy to
;===Check for existing list
IfFileExists "$EXEDIR\FileCleanup.ini" +3
GetTempFileName $0 $EXEDIR
Rename $0 "$EXEDIR\FileCleanup.ini"
;===Add file
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "CopyFiles" "FilesToCopy"
IfErrors 0 +3
ClearErrors
StrCpy $0 0
IntOp $0 $0 + 1
WriteINIStr "$EXEDIR\FileCleanup.ini" "CopyFiles" "FilesToCopy" $0
WriteINIStr "$EXEDIR\FileCleanup.ini" "CopyFiles" "CopyFrom$0" "$1"
WriteINIStr "$EXEDIR\FileCleanup.ini" "CopyFiles" "CopyTo$0" "$2"
Pop $2
Pop $1
FunctionEnd
Function FileCleanup
Push $0
Push $1
Push $2
Push $3
;===Check for file list
IfFileExists "$EXEDIR\FileCleanup.ini" "" Done
;===Copy files
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Remove" "NumberOfFiles"
IfErrors 0 +3
ClearErrors
Goto EndLoop1
StrCmp $0 0 EndLoop1
Loop1:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "CopyFiles" "CopyFrom$0"
ReadINIStr $2 "$EXEDIR\FileCleanup.ini" "CopyFiles" "CopyTo$0"
CopyFiles /SILENT "$1" "$2"
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop1
EndLoop1:
;===Remove files
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Remove" "NumberOfFiles"
IfErrors 0 +3
ClearErrors
Goto EndLoop2
StrCmp $0 0 EndLoop2
Loop2:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Remove" "File$0"
Delete $1
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop2
EndLoop2:
;===Remove folders
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Remove" "NumberOfFolders"
IfErrors 0 +3
ClearErrors
Goto EndLoop3
StrCmp $0 0 EndLoop3
Loop3:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Remove" "Folder$0"
SetOutPath "$1\.."
RMDir /r $1
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop3
EndLoop3:
;===Backup files to keep
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Keep" "NumberOfFiles"
IfErrors 0 +3
ClearErrors
Goto EndLoop4
StrCmp $0 0 EndLoop4
Loop4:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Keep" "File$0"
${GetParent} $1 $2
${GetFileName} $1 $3
SetOutPath "$2_Keep"
Rename $1 "$2_Keep\$3"
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop4
EndLoop4:
;===Backup folders to keep
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Keep" "NumberOfFolders"
IfErrors 0 +3
ClearErrors
Goto EndLoop5
StrCmp $0 0 EndLoop5
Loop5:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Keep" "Folder$0"
${GetParent} $1 $2
${GetFileName} $1 $3
SetOutPath "$2_Keep"
Rename $1 "$2_Keep\$3"
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop5
EndLoop5:
;===Remove unkept files
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Keep" "NumberOfFiles"
IfErrors 0 +3
ClearErrors
Goto EndLoop6
StrCmp $0 0 EndLoop6
Loop6:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Keep" "File$0"
${GetParent} $1 $2
SetOutPath "$2\.."
RMDir /r $2
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop6
EndLoop6:
;===Remove unkept folders
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Keep" "NumberOfFolders"
IfErrors 0 +3
ClearErrors
Goto EndLoop7
StrCmp $0 0 EndLoop7
Loop7:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Keep" "Folder$0"
${GetParent} $1 $2
SetOutPath "$2\.."
RMDir /r $2
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop7
EndLoop7:
;===Restore kept files
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Keep" "NumberOfFiles"
IfErrors 0 +3
ClearErrors
Goto EndLoop8
StrCmp $0 0 EndLoop8
Loop8:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Keep" "File$0"
${GetParent} $1 $2
SetOutPath "$2\.."
IfFileExists "$2_Keep" 0 +3
RMDir /r $2
Rename "$2_Keep" "$2"
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop8
EndLoop8:
;===Restore kept folders
ReadINIStr $0 "$EXEDIR\FileCleanup.ini" "Keep" "NumberOfFolders"
IfErrors 0 +3
ClearErrors
Goto EndLoop9
StrCmp $0 0 EndLoop9
Loop9:
ReadINIStr $1 "$EXEDIR\FileCleanup.ini" "Keep" "Folder$0"
${GetParent} $1 $2
SetOutPath "$2\.."
IfFileExists "$2_Keep" 0 +3
RMDir /r $2
Rename "$2_Keep" "$2"
IntOp $0 $0 - 1
StrCmp $0 0 "" Loop9
EndLoop9:
Delete $EXEDIR\FileCleanup.ini
;===Put the stack back
Done:
Pop $3
Pop $0
Pop $1
Pop $2
FunctionEnd
!macro _AddFileToKeep FILE
Push "${FILE}"
Push "File"
Push "Keep"
Call AddToCleanupList
!macroend
!macro _AddFileToRemove FILE
Push "${FILE}"
Push "File"
Push "Remove"
Call AddToCleanupList
!macroend
!macro _AddFolderToKeep FOLDER
Push "${FOLDER}"
Push "Folder"
Push "Keep"
Call AddToCleanupList
!macroend
!macro _AddFolderToRemove FOLDER
Push "${FOLDER}"
Push "Folder"
Push "Remove"
Call AddToCleanupList
!macroend
!macro _AddFilesToCopy COPYFROM COPYTO
Push "${COPYTO}"
Push "${COPYFROM}"
Call AddToCopyList
!macroend
!define AddFileToKeep '!insertmacro "_AddFileToKeep"'
!define AddFileToRemove '!insertmacro "_AddFileToRemove"'
!define AddFolderToKeep '!insertmacro "_AddFolderToKeep"'
!define AddFolderToRemove '!insertmacro "_AddFolderToRemove"'
!define AddFilesToCopy '!insertmacro "_AddFilesToCopy"'
!define FileCleanup 'Call FileCleanup'
An example of using this would be say you have the following structure inside of a given folder:
folder -\folder1 -\file1 -\file2 -\file3 -\folder2 -\file1 -\file2 -\file3 -\folder3 -\file1 -\file2 -\file3and executed the following:
${AddFileToKeep} "folder\folder1\file1"
${AddFileToRemove} "folder\folder2\file2"
${AddFolderToRemove} "folder\folder3"
${FileCleanup}
You would be left with
folder -\folder1 -\file1 -\folder2 -\file1 -\file3Quamquam omniam nescio, nec nihil scio.