Uninstall only installed files: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
Line 17: Line 17:
LangString UninstLogMissing ${LANG_ENGLISH} "${UninstLog} not found!$\r$\nUninstallation cannot proceed!"
LangString UninstLogMissing ${LANG_ENGLISH} "${UninstLog} not found!$\r$\nUninstallation cannot proceed!"


; Add file macro
; AddItem macro
!macro AddItem Path
FileWrite $UninstLog "${Path}$\r$\n"
!macroend
!define AddItem "!insertmacro AddItem"
 
; File macro
!macro File FilePath FileName
!macro File FilePath FileName
!define FileID ${__LINE__}
  IfFileExists "$OUTDIR\${FileName}" +2
  IfFileExists "$OUTDIR\${FileName}" NoLog_${FileID}
   FileWrite $UninstLog "$OUTDIR\${FileName}$\r$\n"
   FileWrite $UninstLog "$OUTDIR\${FileName}$\r$\n"
NoLog_${FileID}:
  File "${FilePath}${FileName}"
  File "${FilePath}${FileName}"
!undef FileID
!macroend
!macroend
!define File "!insertmacro File"
!define File "!insertmacro File"


; Set output path macro
; Copy files macro
!macro CopyFiles SourcePath DestPath
IfFileExists "${DestPath}" +2
  FileWrite $UninstLog "${DestPath}$\r$\n"
CopyFiles "${SourcePath}" "${DestPath}"
!macroend
!define CopyFiles "!insertmacro CopyFiles"
 
; Rename macro
!macro Rename SourcePath DestPath
IfFileExists "${DestPath}" +2
  FileWrite $UninstLog "${DestPath}$\r$\n"
Rename "${SourcePath}" "${DestPath}"
!macroend
!define Rename "!insertmacro Rename"
 
; CreateDirectory macro
!macro CreateDirectory Path
CreateDirectory "${Path}"
FileWrite $UninstLog "${Path}$\r$\n"
!macroend
!define CreateDirectory "!insertmacro CreateDirectory"
 
; SetOutPath macro
!macro SetOutPath Path
!macro SetOutPath Path
  SetOutPath "${Path}"
  SetOutPath "${Path}"
  FileWrite $UninstLog "${PATH}$\r$\n"
  FileWrite $UninstLog "${Path}$\r$\n"
!macroend
!macroend
!define SetOutPath "!insertmacro SetOutPath"
!define SetOutPath "!insertmacro SetOutPath"
Line 62: Line 88:
  ${SetOutPath} "$INSTDIR\Other"
  ${SetOutPath} "$INSTDIR\Other"
  ${File} "dir2\" "file4.ext"
  ${File} "dir2\" "file4.ext"
${File} "dir2\" "file5.ext"
${File} "dir2\" "file6.ext"
SectionEnd
Section "Copy Files & Rename"
${CreateDirectory} "$INSTDIR\backup"
${CopyFiles} "$INSTDIR\file1.ext" "$INSTDIR\backup\file1.ext"
  ${File} "dir2\" "file5.ext"
  ${File} "dir2\" "file5.ext"
  ${File} "dir2\" "file6.ext"
  ${File} "dir2\" "file6.ext"
Line 82: Line 117:


  Push $R0
  Push $R0
Push $R1
Push $R2
  SetFileAttributes "$INSTDIR\${UninstLog}" NORMAL
  SetFileAttributes "$INSTDIR\${UninstLog}" NORMAL
  FileOpen $UninstLog "$INSTDIR\${UninstLog}" r
  FileOpen $UninstLog "$INSTDIR\${UninstLog}" r
StrCpy $R1 0
GetLineCount:
  ClearErrors
  FileRead $UninstLog $R0
  IntOp $R1 $R1 + 1
  IfErrors GetLineCountDone GetLineCount


  LoopRead:
  LoopRead:
   ClearErrors
   FileSeek $UninstLog SET 0
  StrCpy $R2 0
  FindLine:
   FileRead $UninstLog $R0
   FileRead $UninstLog $R0
   IfErrors LoopDone
   IntOp $R2 $R2 + 1
  StrCpy $R1 $R2 0 FindLine


   Push $R0
   StrCpy $R0 $R0 -2
    Call un.TrimNewLines
  Pop $R0
   IfFileExists "$R0\*.*" 0 +3
   IfFileExists "$R0\*.*" 0 +3
     RMDir /r $R0  #is dir
     RMDir $R0  #is dir
   Goto LoopRead
   Goto LoopRead
     Delete $R0 #is file
     Delete $R0 #is file


  IntOp $R1 $R1 - 1
   Goto LoopRead
   Goto LoopRead
  LoopDone:
  LoopDone:
  FileClose $UninstLog
  FileClose $UninstLog
  Delete "$INSTDIR\${UninstLog}"
  Delete "$INSTDIR\${UninstLog}"
Pop $R2
Pop $R1
  Pop $R0
  Pop $R0



Revision as of 09:41, 12 May 2006

Author: Afrow UK (talk, contrib)


Description

This code was written for Rookie12 a long while back. So many people have asked the same question since, so I thought that it was a good idea to put it up on here. You need the TrimNewLines function present in your script also. Make sure you rename the TrimNewLines function name to un.TrimNewLines (as the function is used in the uninstaller, ala "un.").

The Script

This goes before all your own sections in your script...

!define UninstLog "uninstall.log"
Var UninstLog
 
; Uninstall log file missing.
LangString UninstLogMissing ${LANG_ENGLISH} "${UninstLog} not found!$\r$\nUninstallation cannot proceed!"
 
; AddItem macro
!macro AddItem Path
 FileWrite $UninstLog "${Path}$\r$\n"
!macroend
!define AddItem "!insertmacro AddItem"
 
; File macro
!macro File FilePath FileName
 IfFileExists "$OUTDIR\${FileName}" +2
  FileWrite $UninstLog "$OUTDIR\${FileName}$\r$\n"
 File "${FilePath}${FileName}"
!macroend
!define File "!insertmacro File"
 
; Copy files macro
!macro CopyFiles SourcePath DestPath
 IfFileExists "${DestPath}" +2
  FileWrite $UninstLog "${DestPath}$\r$\n"
 CopyFiles "${SourcePath}" "${DestPath}"
!macroend
!define CopyFiles "!insertmacro CopyFiles"
 
; Rename macro
!macro Rename SourcePath DestPath
 IfFileExists "${DestPath}" +2
  FileWrite $UninstLog "${DestPath}$\r$\n"
 Rename "${SourcePath}" "${DestPath}"
!macroend
!define Rename "!insertmacro Rename"
 
; CreateDirectory macro
!macro CreateDirectory Path
 CreateDirectory "${Path}"
 FileWrite $UninstLog "${Path}$\r$\n"
!macroend
!define CreateDirectory "!insertmacro CreateDirectory"
 
; SetOutPath macro
!macro SetOutPath Path
 SetOutPath "${Path}"
 FileWrite $UninstLog "${Path}$\r$\n"
!macroend
!define SetOutPath "!insertmacro SetOutPath"
 
Section -openlogfile
 IfFileExists "$INSTDIR\${UninstLog}" +3
  FileOpen $UninstLog "$INSTDIR\${UninstLog}" w
 Goto +4
  SetFileAttributes "$INSTDIR\${UninstLog}" NORMAL
  FileOpen $UninstLog "$INSTDIR\${UninstLog}" a
  FileSeek $UninstLog 0 END
SectionEnd

Your own sections need to be placed here in your script.
Instead of using SetOutPath and File instructions in your sections, use ${SetOutPath} and ${File} instead.

This is an example of what your sections may now look like...

Section "Install Main"
 
 ${SetOutPath} $INSTDIR
 ${File} "dir1\" "file1.ext"
 ${File} "dir1\" "file2.ext"
 ${File} "dir1\" "file3.ext"
 
SectionEnd
 
Section "Install Other"
 
 ${SetOutPath} "$INSTDIR\Other"
 ${File} "dir2\" "file4.ext"
 ${File} "dir2\" "file5.ext"
 ${File} "dir2\" "file6.ext"
 
SectionEnd
 
Section "Copy Files & Rename"
 
 ${CreateDirectory} "$INSTDIR\backup"
 ${CopyFiles} "$INSTDIR\file1.ext" "$INSTDIR\backup\file1.ext"
 ${File} "dir2\" "file5.ext"
 ${File} "dir2\" "file6.ext"
 
SectionEnd

This comes after all your own sections in your script...

Section -closelogfile
 FileClose $UninstLog
 SetFileAttributes "$INSTDIR\${UninstLog}" READONLY|SYSTEM|HIDDEN
SectionEnd
 
Section Uninstall
 
 ; Can't uninstall if uninstall log is missing!
 IfFileExists "$INSTDIR\${UninstLog}" +3
  MessageBox MB_OK|MB_ICONSTOP "$(UninstLogMissing)"
   Abort
 
 Push $R0
 Push $R1
 Push $R2
 SetFileAttributes "$INSTDIR\${UninstLog}" NORMAL
 FileOpen $UninstLog "$INSTDIR\${UninstLog}" r
 StrCpy $R1 0
 
 GetLineCount:
  ClearErrors
   FileRead $UninstLog $R0
   IntOp $R1 $R1 + 1
   IfErrors GetLineCountDone GetLineCount
 
 LoopRead:
  FileSeek $UninstLog SET 0
  StrCpy $R2 0
  FindLine:
   FileRead $UninstLog $R0
   IntOp $R2 $R2 + 1
   StrCpy $R1 $R2 0 FindLine
 
   StrCpy $R0 $R0 -2
   IfFileExists "$R0\*.*" 0 +3
    RMDir $R0  #is dir
   Goto LoopRead
    Delete $R0 #is file
 
  IntOp $R1 $R1 - 1
  Goto LoopRead
 LoopDone:
 FileClose $UninstLog
 Delete "$INSTDIR\${UninstLog}"
 Pop $R2
 Pop $R1
 Pop $R0
 
SectionEnd

-Stu