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:
and executed the following:
${AddFileToKeep} "folder\folder1\file1"
${AddFileToRemove} "folder\folder2\file2"
${AddFolderToRemove} "folder\folder3"
${FileCleanup}
You would be left with
Quamquam omniam nescio, nec nihil scio.