Windows installer: uninstall only what was installed
parent
8c9ca07b3f
commit
49a24da23d
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
|
||||
NSIS Uninstaller Data
|
||||
Copyright 2014 Aleksandr Ivankiv
|
||||
|
||||
Modified by the Betaflight Team project to let it be used out of the uninstall section
|
||||
*/
|
||||
|
||||
;--------------------------------
|
||||
|
||||
!ifndef UNINST_INCLUDED
|
||||
!define UNINST_INCLUDED
|
||||
|
||||
!verbose push
|
||||
!verbose 3
|
||||
|
||||
!ifndef UNINST_VERBOSE
|
||||
!define UNINST_VERBOSE 3
|
||||
!endif
|
||||
|
||||
!verbose ${UNINST_VERBOSE}
|
||||
|
||||
;--------------------------------
|
||||
;Header files required by Uninstaller Data
|
||||
|
||||
!include "FileFunc.nsh"
|
||||
!include "TextFunc.nsh"
|
||||
|
||||
;--------------------------------
|
||||
;Variables
|
||||
|
||||
Var List
|
||||
Var Log
|
||||
Var Tmp
|
||||
Var UNINST_DAT
|
||||
Var UNINST_EXE
|
||||
Var UNINST_DEL_FILE
|
||||
|
||||
;--------------------------------
|
||||
;Default language strings
|
||||
|
||||
!define UNINST_EXCLUDE_ERROR_DEFAULT "Error creating an exclusion list."
|
||||
!define UNINST_DATA_ERROR_DEFAULT "Error creating the uninstaller data: $\r$\nCannot find an exclusion list."
|
||||
!define UNINST_DAT_NOT_FOUND_DEFAULT "$UNINST_DAT not found, unable to perform uninstall. Manually delete files."
|
||||
!define UNINST_DAT_MISSING_DEFAULT "$UNINST_DAT is missing, some elements could not be removed. These can be removed manually."
|
||||
!define UNINST_DEL_FILE_DEFAULT "Delete File"
|
||||
|
||||
;--------------------------------
|
||||
;Language strings macro
|
||||
|
||||
!macro SETSTRING NAME
|
||||
|
||||
!ifndef "${NAME}"
|
||||
!ifdef UNINST_LOCALIZE
|
||||
!define "${NAME}" "$(${NAME})"
|
||||
!else
|
||||
!define "${NAME}" "${${NAME}_DEFAULT}"
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!macroend
|
||||
|
||||
;--------------------------------
|
||||
;Initialization macro
|
||||
|
||||
!macro UNINST_INIT
|
||||
|
||||
;Default settings
|
||||
!ifndef UninstName
|
||||
!define UninstName "Uninstall"
|
||||
!endif
|
||||
!ifndef UninstHeader
|
||||
!define UninstHeader "=========== Uninstaller Data please do not edit this file ==========="
|
||||
!endif
|
||||
!insertmacro SETSTRING "UNINST_EXCLUDE_ERROR"
|
||||
!insertmacro SETSTRING "UNINST_DATA_ERROR"
|
||||
!insertmacro SETSTRING "UNINST_DAT_NOT_FOUND"
|
||||
!insertmacro SETSTRING "UNINST_DAT_MISSING"
|
||||
!insertmacro SETSTRING "UNINST_DEL_FILE"
|
||||
StrCpy $UNINST_DEL_FILE "${UNINST_DEL_FILE}"
|
||||
StrCpy $UNINST_DAT "$OUTDIR\${UninstName}.dat"
|
||||
StrCpy $UNINST_EXE "$OUTDIR\${UninstName}.exe"
|
||||
|
||||
!macroend
|
||||
|
||||
;--------------------------------
|
||||
;Change name of file
|
||||
|
||||
!macro UNINST_NAME Name
|
||||
|
||||
!ifdef UninstName
|
||||
!undef UninstName
|
||||
!define UninstName "${Name}"
|
||||
!else
|
||||
!define UninstName "${Name}"
|
||||
!endif
|
||||
!insertmacro UNINST_INIT
|
||||
|
||||
!macroend
|
||||
|
||||
;--------------------------------
|
||||
;Create an exclusion list
|
||||
|
||||
!macro UNINSTALLER_DATA_BEGIN
|
||||
|
||||
!insertmacro UNINST_EXCLUDE
|
||||
|
||||
!macroend
|
||||
|
||||
!macro UNINST_EXCLUDE
|
||||
|
||||
!verbose push
|
||||
!verbose ${UNINST_VERBOSE}
|
||||
|
||||
!insertmacro UNINST_INIT
|
||||
|
||||
StrCmp "$PLUGINSDIR" "" 0 +2
|
||||
InitPluginsDir
|
||||
|
||||
GetTempFileName $Tmp $PLUGINSDIR
|
||||
|
||||
IfErrors 0 UninstExclude
|
||||
!ifndef UNINST_ERROR
|
||||
!define UNINST_ERROR
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_EXCLUDE_ERROR}" /SD IDOK
|
||||
Goto +3
|
||||
!endif
|
||||
|
||||
UninstExclude:
|
||||
FileOpen $List "$Tmp" w
|
||||
${Locate} "$OUTDIR" "/L=FD" "${ExcludeList_Func_CallBack}"
|
||||
FileClose $List
|
||||
|
||||
!verbose pop
|
||||
|
||||
!macroend
|
||||
|
||||
!macro UNINST_FUNCTION_EXCLUDELIST
|
||||
|
||||
Function ExcludeList
|
||||
|
||||
FileWrite $List "$R9$\r$\n"
|
||||
Push $0
|
||||
|
||||
FunctionEnd
|
||||
|
||||
!macroend
|
||||
|
||||
!ifndef ExcludeList_Func_CallBack
|
||||
!insertmacro UNINST_FUNCTION_EXCLUDELIST
|
||||
!define ExcludeList_Func_CallBack "ExcludeList"
|
||||
!endif
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;Write Uninstaller Data
|
||||
|
||||
!macro UNINSTALLER_DATA_END
|
||||
|
||||
!insertmacro UNINST_DATA
|
||||
|
||||
!macroend
|
||||
|
||||
!macro UNINST_DATA
|
||||
|
||||
!verbose push
|
||||
!verbose ${UNINST_VERBOSE}
|
||||
|
||||
!insertmacro UNINST_INIT
|
||||
|
||||
IfFileExists "$Tmp" UninstData
|
||||
!ifndef UNINST_ERROR
|
||||
!define UNINST_ERROR
|
||||
${GetFileName} "$UNINST_DAT" $R0
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_DATA_ERROR}" /SD IDOK
|
||||
!endif
|
||||
Goto DoneUninstData
|
||||
|
||||
UninstData:
|
||||
FileOpen $Log "$UNINST_DAT" a
|
||||
FileOpen $List "$Tmp" r
|
||||
|
||||
FileRead $Log $1
|
||||
IfErrors 0 +2
|
||||
FileWrite $Log "${UninstHeader}$\r$\n"
|
||||
|
||||
${Locate} "$OUTDIR" "/L=FD" "${UninstallData_Func_CallBack}"
|
||||
|
||||
FileClose $List
|
||||
FileClose $Log
|
||||
|
||||
DoneUninstData:
|
||||
StrCpy $Tmp ""
|
||||
|
||||
!verbose pop
|
||||
|
||||
!macroend
|
||||
|
||||
!macro UNINST_FUNCTION_UNINSTDATA
|
||||
|
||||
Function UninstallData
|
||||
|
||||
StrCmp $R9 $UNINST_DAT Done
|
||||
|
||||
FileSeek $List 0 SET
|
||||
|
||||
LoopReadList:
|
||||
FileRead $List $1 ${NSIS_MAX_STRLEN}
|
||||
IfErrors DoneReadList
|
||||
|
||||
${TrimNewLines} $1 $R0
|
||||
StrCmp $R0 $R9 Done
|
||||
|
||||
Goto LoopReadList
|
||||
|
||||
DoneReadList:
|
||||
FileSeek $Log 0 SET
|
||||
|
||||
LoopReadLog:
|
||||
FileRead $Log $1 ${NSIS_MAX_STRLEN}
|
||||
IfErrors DoneReadLog
|
||||
|
||||
${TrimNewLines} $1 $R0
|
||||
StrCmp $R0 $R9 Done
|
||||
|
||||
Goto LoopReadLog
|
||||
|
||||
DoneReadLog:
|
||||
FileSeek $Log 0 END
|
||||
FileWrite $Log "$R9$\r$\n"
|
||||
|
||||
Done:
|
||||
Push $0
|
||||
|
||||
FunctionEnd
|
||||
|
||||
!macroend
|
||||
|
||||
!ifndef UninstallData_Func_CallBack
|
||||
!insertmacro UNINST_FUNCTION_UNINSTDATA
|
||||
!define UninstallData_Func_CallBack "UninstallData"
|
||||
!endif
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;Uninstall Files
|
||||
|
||||
!macro INST_DELETE Path Name
|
||||
!insertmacro UNINST_DELETE_MULTIPLE ${Path} ${Name} ""
|
||||
!macroend
|
||||
|
||||
!macro UNINST_DELETE Path Name
|
||||
!insertmacro UNINST_DELETE_MULTIPLE ${Path} ${Name} "un."
|
||||
!macroend
|
||||
|
||||
!macro UNINST_DELETE_MULTIPLE Path Name un
|
||||
|
||||
!verbose push
|
||||
!verbose ${UNINST_VERBOSE}
|
||||
|
||||
!if "${Path}" == ""
|
||||
StrCpy $OUTDIR "$INSTDIR"
|
||||
!else
|
||||
StrCpy $OUTDIR "${Path}"
|
||||
!endif
|
||||
!if "${Name}" == ""
|
||||
!insertmacro UNINST_NAME "Uninstall"
|
||||
!else
|
||||
!insertmacro UNINST_NAME "${Name}"
|
||||
!endif
|
||||
|
||||
!insertmacro UNINST_INIT
|
||||
|
||||
IfFileExists "$UNINST_DAT" +3
|
||||
!ifdef UNINST_TERMINATE
|
||||
MessageBox MB_OK|MB_ICONSTOP "${UNINST_DAT_NOT_FOUND}" /SD IDOK
|
||||
Quit
|
||||
!else
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_DAT_MISSING}" /SD IDOK
|
||||
StrCpy $0 "error"
|
||||
!endif
|
||||
|
||||
${If} $0 != "error"
|
||||
|
||||
FileOpen $Log "$UNINST_DAT" r
|
||||
Call ${un}DeleteList
|
||||
FileClose $Log
|
||||
|
||||
Delete "$UNINST_DAT"
|
||||
|
||||
!ifdef UNINST_INTERACTIVE
|
||||
${Locate} "$OUTDIR" "/L=F" "${un.InterActive_Func_CallBack}"
|
||||
${Locate} "$OUTDIR" "/L=DE" "${un.InterActive_Func_CallBack}"
|
||||
!else
|
||||
Call ${un}InterActive
|
||||
!endif
|
||||
|
||||
${Else}
|
||||
StrCpy $0 ""
|
||||
${EndIf}
|
||||
|
||||
Delete "$UNINST_EXE"
|
||||
RMDir $OUTDIR
|
||||
ClearErrors
|
||||
|
||||
!verbose pop
|
||||
|
||||
!macroend
|
||||
|
||||
!macro UNINST_FUNCTION_DELETE un
|
||||
|
||||
Function ${un}DeleteList
|
||||
|
||||
LoopReadFile:
|
||||
FileRead $Log $1 ${NSIS_MAX_STRLEN}
|
||||
IfErrors DoneReadFile
|
||||
|
||||
${TrimNewLines} $1 $R0
|
||||
|
||||
IfFileExists $R0\*.* +3
|
||||
IfFileExists $R0 0 +2
|
||||
Delete $R0
|
||||
|
||||
Goto LoopReadFile
|
||||
|
||||
DoneReadFile:
|
||||
FileSeek $Log 0 SET
|
||||
|
||||
LoopReadDIR:
|
||||
FileRead $Log $1 ${NSIS_MAX_STRLEN}
|
||||
IfErrors DoneReadDIR
|
||||
|
||||
${TrimNewLines} $1 $R0
|
||||
|
||||
IfFileExists $R0\*.* 0 +3
|
||||
RMDir $R0
|
||||
ClearErrors
|
||||
|
||||
Goto LoopReadDIR
|
||||
|
||||
DoneReadDIR:
|
||||
|
||||
FunctionEnd
|
||||
|
||||
!macroend
|
||||
|
||||
!insertmacro UNINST_FUNCTION_DELETE ""
|
||||
!insertmacro UNINST_FUNCTION_DELETE "un."
|
||||
|
||||
!macro UNINST_FUNCTION_INTERACTIVE un
|
||||
|
||||
Function ${un}InterActive
|
||||
|
||||
StrCmp $R9 "" +8
|
||||
IfFileExists $R9\*.* 0 +3
|
||||
RMDir $R9
|
||||
Goto +4
|
||||
StrCmp $R9 $UNINST_EXE +3
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "$UNINST_DEL_FILE '$R9'?" /SD IDNO IDNO +2
|
||||
Delete $R9
|
||||
Push $0
|
||||
|
||||
FunctionEnd
|
||||
|
||||
!macroend
|
||||
|
||||
!ifndef un.InterActive_Func_CallBack
|
||||
!insertmacro UNINST_FUNCTION_INTERACTIVE "un."
|
||||
!define un.InterActive_Func_CallBack "un.InterActive"
|
||||
!endif
|
||||
|
||||
!ifndef InterActive_Func_CallBack
|
||||
!insertmacro UNINST_FUNCTION_INTERACTIVE ""
|
||||
!define InterActive_Func_CallBack "InterActive"
|
||||
!endif
|
||||
|
||||
!verbose pop
|
||||
|
||||
!endif
|
|
@ -1,6 +1,7 @@
|
|||
!include "MUI2.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!include "LogicLib.nsh"
|
||||
!include "UnInst.nsh"
|
||||
|
||||
# Receives variables from the command line
|
||||
# ${VERSION} - Version to generate (x.y.z)
|
||||
|
@ -26,6 +27,9 @@ BrandingText "${COMPANY_NAME}"
|
|||
!define MUI_ICON ".\bf_installer_icon.ico"
|
||||
!define MUI_UNICON ".\bf_uninstaller_icon.ico"
|
||||
|
||||
#Define uninstall list name
|
||||
!define UninstName "UninstallBF"
|
||||
|
||||
# Request rights user level
|
||||
RequestExecutionLevel highest
|
||||
|
||||
|
@ -48,6 +52,7 @@ OutFile "..\..\${DEST_FOLDER}\${FILE_NAME_INSTALLER}"
|
|||
!insertmacro MUI_LANGUAGE "Korean"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
|
||||
# detect default install folder
|
||||
Function .onInit
|
||||
|
||||
# Check if older version
|
||||
|
@ -102,19 +107,35 @@ Section
|
|||
|
||||
${If} $R4 != ""
|
||||
# delete the installed files of the older version
|
||||
RMDir /r $R4
|
||||
!insertmacro INST_DELETE $R4 "${UninstName}"
|
||||
|
||||
# remove installation folder if empty
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
# if the registry entries did not exist, we ignore the errors
|
||||
ClearErrors
|
||||
|
||||
# define the path to which the installer should install
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
# create an exclusion list for the uninstaller
|
||||
!insertmacro UNINSTALLER_DATA_BEGIN
|
||||
|
||||
# specify the files to go in the output path
|
||||
File /r ${SOURCE_FILES}
|
||||
|
||||
# create the uninstaller
|
||||
WriteUninstaller "$INSTDIR\${FILE_NAME_UNINSTALLER}"
|
||||
|
||||
# change uninstall list name
|
||||
!insertmacro UNINST_NAME "unins000BF"
|
||||
|
||||
# store uninstaller data
|
||||
!insertmacro UNINSTALLER_DATA_END
|
||||
|
||||
# create shortcuts in the start menu and on the desktop
|
||||
CreateDirectory "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_EXECUTABLE}"
|
||||
|
@ -152,8 +173,14 @@ SectionEnd
|
|||
# create a section to define what the uninstaller does
|
||||
Section "Uninstall"
|
||||
|
||||
# delete the installed files
|
||||
RMDir /r $INSTDIR
|
||||
# terminate uninstaller if the .dat file does not exist
|
||||
!define UNINST_TERMINATE
|
||||
|
||||
# delete files
|
||||
!insertmacro UNINST_DELETE "$INSTDIR" "${UninstName}"
|
||||
|
||||
# remove installation folder if it is empty
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
# delete the shortcuts
|
||||
Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME}.lnk"
|
||||
|
@ -163,7 +190,7 @@ Section "Uninstall"
|
|||
RMDir "$SMPROGRAMS\${GROUP_NAME}"
|
||||
Delete "$DESKTOP\${APP_NAME}.lnk"
|
||||
|
||||
# remove from add/remove programs
|
||||
# remove from registry
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
|
||||
DeleteRegKey HKCU "Software\${GROUP_NAME}\${APP_NAME}"
|
||||
DeleteRegKey /ifempty HKCU "Software\${GROUP_NAME}"
|
||||
|
|
Loading…
Reference in New Issue