NSIS header for file cleanup![]() qwertymodo - April 3, 2009 - 4:09am
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 ${AddFolderToKeep} FOLDER ${AddFileToRemove} FILE ${AddFolderToRemove} FOLDER ${AddFilesToCopy} COPYFROM COPYTO ${FileCleanup}
;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'
( categories: )
|


An example
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.