-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathUninstall.nsh
More file actions
executable file
·165 lines (132 loc) · 6.32 KB
/
Copy pathUninstall.nsh
File metadata and controls
executable file
·165 lines (132 loc) · 6.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
NsisMultiUser.nsh - NSIS plugin that allows "per-user" (no admin required) and "per-machine" (asks elevation *only when necessary*) installations
Full source code, documentation and demos at https://github.com/Drizin/NsisMultiUser/
Copyright 2016-2019 Ricardo Drizin, Alex Mitev
File : Demos\UMUI_Ex_Full\Uninstall.nsh
Version: 2019-07-24
*/
!include un.Utils.nsh
; Variables
Var SemiSilentMode ; installer started uninstaller in semi-silent mode using /SS parameter
Var RunningFromInstaller ; installer started uninstaller using /uninstall parameter
Var RunningAsShellUser ; uninstaller restarted itself under the user of the running shell
Section "un.Program Files" SectionUninstallProgram
SectionIn RO
; Ultra Modern UI modifies shell var context, see http://forums.winamp.com/showthread.php?t=399898
${if} $MultiUser.InstallMode == "AllUsers"
SetShellVarContext all
${else}
SetShellVarContext current
${endif}
!insertmacro MULTIUSER_GetCurrentUserString $0
; InvokeShellVerb only works on existing files, so we call it before deleting the EXE, https://github.com/lordmulder/stdutils/issues/22
; Clean up "Start Menu Icon"
${if} ${AtLeastWin7}
${StdUtils.InvokeShellVerb} $1 "$INSTDIR" "${PROGEXE}" ${StdUtils.Const.ShellVerb.UnpinFromStart}
${else}
!insertmacro DeleteRetryAbort "$STARTMENU\${PRODUCT_NAME}$0.lnk"
${endif}
; Clean up "Quick Launch Icon"
${if} ${AtLeastWin7}
${StdUtils.InvokeShellVerb} $1 "$INSTDIR" "${PROGEXE}" ${StdUtils.Const.ShellVerb.UnpinFromTaskbar}
${else}
!insertmacro DeleteRetryAbort "$QUICKLAUNCH\${PRODUCT_NAME}.lnk"
${endif}
; Try to delete the EXE as the first step - if it's in use, don't remove anything else
!insertmacro DeleteRetryAbort "$INSTDIR\${PROGEXE}"
!ifdef LICENSE_FILE
!insertmacro DeleteRetryAbort "$INSTDIR\${LICENSE_FILE}"
!endif
; Clean up "Documentation"
!insertmacro DeleteRetryAbort "$INSTDIR\readme.txt"
; Clean up "Program Group" - we check that we created Start menu folder, if $StartMenuFolder is empty, the whole $SMPROGRAMS directory will be removed!
${if} "$StartMenuFolder" != ""
RMDir /r "$SMPROGRAMS\$StartMenuFolder"
${endif}
; Clean up "Dektop Icon"
!insertmacro DeleteRetryAbort "$DESKTOP\${PRODUCT_NAME}$0.lnk"
SectionEnd
Section /o "un.Program Settings" SectionRemoveSettings
; this section is executed only explicitly and shouldn't be placed in SectionUninstallProgram
DeleteRegKey HKCU "Software\${PRODUCT_NAME}"
SectionEnd
Section "-Uninstall" ; hidden section, must always be the last one!
Delete "$INSTDIR\${UNINSTALL_FILENAME}" ; we cannot use un.DeleteRetryAbort here - when using the _? parameter the uninstaller cannot delete itself and Delete fails, which is OK
; remove the directory only if it is empty - the user might have saved some files in it
RMDir "$INSTDIR"
; Remove the uninstaller from registry as the very last step - if sth. goes wrong, let the user run it again
!insertmacro MULTIUSER_RegistryRemoveInstallInfo ; Remove registry keys
; If the uninstaller still exists, use cmd.exe on exit to remove it (along with $INSTDIR if it's empty)
${if} ${FileExists} "$INSTDIR\${UNINSTALL_FILENAME}"
Exec 'cmd.exe /c (del /f /q "$INSTDIR\${UNINSTALL_FILENAME}") && (rmdir "$INSTDIR")'
${endif}
SectionEnd
; Modern install component descriptions
!insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SectionUninstallProgram} "Uninstall ${PRODUCT_NAME} files."
!insertmacro MUI_DESCRIPTION_TEXT ${SectionRemoveSettings} "Remove ${PRODUCT_NAME} program settings. Select only if you don't plan to use the program in the future."
!insertmacro MUI_UNFUNCTION_DESCRIPTION_END
; Callbacks
Function un.onInit
${GetParameters} $R0
${GetOptions} $R0 "/uninstall" $R1
${ifnot} ${errors}
StrCpy $RunningFromInstaller 1
${else}
StrCpy $RunningFromInstaller 0
${endif}
${GetOptions} $R0 "/SS" $R1
${ifnot} ${errors}
StrCpy $SemiSilentMode 1
StrCpy $RunningFromInstaller 1
SetAutoClose true ; auto close (if no errors) if we are called from the installer; if there are errors, will be automatically set to false
${else}
StrCpy $SemiSilentMode 0
${endif}
${GetOptions} $R0 "/shelluser" $R1
${ifnot} ${errors}
StrCpy $RunningAsShellUser 1
${else}
StrCpy $RunningAsShellUser 0
${endif}
${ifnot} ${UAC_IsInnerInstance}
${andif} $RunningFromInstaller = 0
; Restarting the uninstaller using the user of the running shell, in order to overcome the Windows bugs that:
; - Elevates the uninstallers of single-user installations when called from 'Apps & features' of Windows 10
; causing them to fail when using a different account for elevation.
; - Elevates the uninstallers of all-users installations when called from 'Add/Remove Programs' of Control Panel,
; preventing them of eleveting on their own and correctly recognize the user that started the uninstaller. If a
; different account was used for elevation, all user-context operations will be performed for the user of that
; account. In this case, the fix causes the elevetion prompt to be displayed twice (one from Control Panel and
; one from the uninstaller).
${if} ${UAC_IsAdmin}
${andif} $RunningAsShellUser = 0
${StdUtils.ExecShellAsUser} $0 "$INSTDIR\${UNINSTALL_FILENAME}" "open" "/shelluser $R0"
Quit
${endif}
!insertmacro CheckSingleInstance "Setup" "Global" "${SETUP_MUTEX}"
!insertmacro CheckSingleInstance "Application" "Local" "${APP_MUTEX}"
${endif}
!insertmacro MULTIUSER_UNINIT
!insertmacro UMUI_MULTILANG_GET ; we always get the language, since the outer and inner instance might have different language
FunctionEnd
Function un.PageInstallModeChangeMode
!insertmacro MUI_STARTMENU_GETFOLDER "" $StartMenuFolder
FunctionEnd
Function un.PageComponentsPre
${if} $SemiSilentMode = 1
Abort ; if user is installing, no use to remove program settings anyway (should be compatible with all versions)
${endif}
FunctionEnd
Function un.PageComponentsShow
; Show/hide the Back button
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 $UninstallShowBackButton
FunctionEnd
Function un.onUninstFailed
${if} $SemiSilentMode = 0
MessageBox MB_ICONSTOP "${PRODUCT_NAME} ${VERSION} could not be fully uninstalled.$\r$\nPlease, restart Windows and run the uninstaller again." /SD IDOK
${else}
MessageBox MB_ICONSTOP "${PRODUCT_NAME} could not be fully installed.$\r$\nPlease, restart Windows and run the setup program again." /SD IDOK
${endif}
FunctionEnd