uninstaller.nsi (42606B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 # Required Plugins: 6 # AppAssocReg 7 # http://nsis.sourceforge.net/Application_Association_Registration_plug-in 8 # BitsUtils 9 # http://searchfox.org/mozilla-central/source/other-licenses/nsis/Contrib/BitsUtils 10 # CityHash 11 # http://searchfox.org/mozilla-central/source/other-licenses/nsis/Contrib/CityHash 12 # HttpPostFile 13 # http://searchfox.org/mozilla-central/source/other-licenses/nsis/Contrib/HttpPostFile 14 # ShellLink 15 # http://nsis.sourceforge.net/ShellLink_plug-in 16 # UAC 17 # http://nsis.sourceforge.net/UAC_plug-in 18 19 ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs 20 !verbose 3 21 22 ; 7-Zip provides better compression than the lzma from NSIS so we add the files 23 ; uncompressed and use 7-Zip to create a SFX archive of it 24 SetDatablockOptimize on 25 SetCompress off 26 CRCCheck on 27 28 RequestExecutionLevel user 29 30 Unicode true 31 ManifestSupportedOS all 32 ManifestDPIAware true 33 34 !addplugindir ./ 35 36 ; Attempt to elevate Standard Users in addition to users that 37 ; are a member of the Administrators group. 38 !define NONADMIN_ELEVATE 39 40 ; prevents compiling of the reg write logging. 41 !define NO_LOG 42 43 !define MaintUninstallKey \ 44 "Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenanceService" 45 46 Var TmpVal 47 Var MaintCertKey 48 Var ShouldOpenSurvey 49 Var ShouldSendPing 50 Var InstalledVersion 51 Var InstalledBuildID 52 Var ShouldPromptForRefresh 53 Var RefreshRequested 54 ; AddTaskbarSC is defined here in order to silence warnings from inside 55 ; MigrateTaskBarShortcut and is not intended to be used here. 56 ; See Bug 1329869 for more. 57 Var AddTaskbarSC 58 ; Will be the registry hive that we are going to write things like class keys 59 ; into. This will generally be HKLM if running with elevation, otherwise HKCU. 60 Var RegHive 61 62 ; Other included files may depend upon these includes! 63 ; The following includes are provided by NSIS. 64 !include FileFunc.nsh 65 !include InstallOptions.nsh 66 !include LogicLib.nsh 67 !include MUI.nsh 68 !include WinMessages.nsh 69 !include WinVer.nsh 70 !include WordFunc.nsh 71 72 !insertmacro GetSize 73 !insertmacro StrFilter 74 !insertmacro WordReplace 75 76 !insertmacro un.GetParent 77 78 ; The following includes are custom. 79 !include branding.nsi 80 !include defines.nsi 81 !include common.nsh 82 !include locales.nsi 83 84 ; This is named BrandShortName helper because we use this for software update 85 ; post update cleanup. 86 VIAddVersionKey "FileDescription" "${BrandShortName} Helper" 87 VIAddVersionKey "OriginalFilename" "helper.exe" 88 89 !insertmacro AddDisabledDDEHandlerValues 90 !insertmacro CleanVirtualStore 91 !insertmacro ElevateUAC 92 !insertmacro GetLongPath 93 !insertmacro GetPathFromString 94 !insertmacro InitHashAppModelId 95 !insertmacro IsHandlerForInstallDir 96 !insertmacro IsPinnedToTaskBar 97 !insertmacro IsUserAdmin 98 !insertmacro LogDesktopShortcut 99 !insertmacro LogQuickLaunchShortcut 100 !insertmacro LogStartMenuShortcut 101 !insertmacro PinnedToStartMenuLnkCount 102 !insertmacro RegCleanAppHandler 103 !insertmacro RegCleanMain 104 !insertmacro RegCleanUninstall 105 !insertmacro SetAppLSPCategories 106 !insertmacro SetBrandNameVars 107 !insertmacro UpdateShortcutAppModelIDs 108 !insertmacro UnloadUAC 109 !insertmacro WriteRegDWORD2 110 !insertmacro WriteRegStr2 111 112 !insertmacro un.ChangeMUIHeaderImage 113 !insertmacro un.ChangeMUISidebarImage 114 !insertmacro un.CheckForFilesInUse 115 !insertmacro un.CleanMaintenanceServiceLogs 116 !insertmacro un.CleanVirtualStore 117 !insertmacro un.DeleteShortcuts 118 !insertmacro un.GetCommonDirectory 119 !insertmacro un.GetLongPath 120 !insertmacro un.GetSecondInstallPath 121 !insertmacro un.InitHashAppModelId 122 !insertmacro un.ManualCloseAppPrompt 123 !insertmacro un.RegCleanAppHandler 124 !insertmacro un.RegCleanFileHandler 125 !insertmacro un.RegCleanMain 126 !insertmacro un.RegCleanPrefs 127 !insertmacro un.RegCleanUninstall 128 !insertmacro un.RegCleanProtocolHandler 129 !insertmacro un.RemoveQuotesFromPath 130 !insertmacro un.RemovePrecompleteEntries 131 !insertmacro un.SetAppLSPCategories 132 !insertmacro un.SetBrandNameVars 133 134 !include shared.nsh 135 136 ; Helper macros for ui callbacks. Insert these after shared.nsh 137 !insertmacro OnEndCommon 138 !insertmacro UninstallOnInitCommon 139 140 !insertmacro un.OnEndCommon 141 !insertmacro un.UninstallUnOnInitCommon 142 143 Name "${BrandFullName}" 144 OutFile "helper.exe" 145 !ifdef HAVE_64BIT_BUILD 146 InstallDir "$PROGRAMFILES64\${BrandFullName}\" 147 !else 148 InstallDir "$PROGRAMFILES32\${BrandFullName}\" 149 !endif 150 ShowUnInstDetails nevershow 151 152 !define URLUninstallSurvey "https://qsurvey.mozilla.com/s3/FF-Desktop-Post-Uninstall?channel=${UpdateChannel}&version=${AppVersion}&osversion=" 153 154 ; Support for the profile refresh feature 155 !define URLProfileRefreshHelp "https://support.mozilla.org/kb/refresh-firefox-reset-add-ons-and-settings" 156 157 ; Arguments to add to the command line when launching FileMainEXE for profile refresh 158 !define ArgsProfileRefresh "-reset-profile -migration -uninstaller-profile-refresh" 159 160 ################################################################################ 161 # Modern User Interface - MUI 162 163 !define MUI_ABORTWARNING 164 !define MUI_ICON setup.ico 165 !define MUI_UNICON setup.ico 166 !define MUI_WELCOMEPAGE_TITLE_3LINES 167 !define MUI_HEADERIMAGE 168 !define MUI_HEADERIMAGE_RIGHT 169 !define MUI_UNWELCOMEFINISHPAGE_BITMAP wizWatermark.bmp 170 ; By default MUI_BGCOLOR is hardcoded to FFFFFF, which is only correct if the 171 ; the Windows theme or high-contrast mode hasn't changed it, so we need to 172 ; override that with GetSysColor(COLOR_WINDOW) (this string ends up getting 173 ; passed to SetCtlColors, which uses this custom syntax to mean that). 174 !define MUI_BGCOLOR SYSCLR:WINDOW 175 176 ; Use a right to left header image when the language is right to left 177 !ifdef ${AB_CD}_rtl 178 !define MUI_HEADERIMAGE_BITMAP_RTL wizHeaderRTL.bmp 179 !else 180 !define MUI_HEADERIMAGE_BITMAP wizHeader.bmp 181 !endif 182 183 !define MUI_CUSTOMFUNCTION_UNGUIINIT un.GUIInit 184 185 /** 186 * Uninstall Pages 187 */ 188 ; Welcome Page 189 !define MUI_PAGE_CUSTOMFUNCTION_PRE un.preWelcome 190 !define MUI_PAGE_CUSTOMFUNCTION_SHOW un.showWelcome 191 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.leaveWelcome 192 !insertmacro MUI_UNPAGE_WELCOME 193 194 ; Custom Uninstall Confirm Page 195 UninstPage custom un.preConfirm 196 197 ; Remove Files Page 198 !insertmacro MUI_UNPAGE_INSTFILES 199 200 ; Finish Page 201 !define MUI_FINISHPAGE_SHOWREADME 202 !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED 203 !define MUI_FINISHPAGE_SHOWREADME_TEXT $(UN_SURVEY_CHECKBOX_LABEL) 204 !define MUI_FINISHPAGE_SHOWREADME_FUNCTION un.Survey 205 !define MUI_PAGE_CUSTOMFUNCTION_PRE un.preFinish 206 !define MUI_PAGE_CUSTOMFUNCTION_SHOW un.showFinish 207 !insertmacro MUI_UNPAGE_FINISH 208 209 ; Use the default dialog for IDD_VERIFY for a simple Banner 210 ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe" 211 212 ################################################################################ 213 # Helper Functions 214 215 Function un.Survey 216 ; We can't actually call ExecInExplorer here because it's going to have to 217 ; make some marshalled COM calls and those are not allowed from within a 218 ; synchronous message handler (where we currently are); we'll be thrown 219 ; RPC_E_CANTCALLOUT_ININPUTSYNCCALL if we try. So all we can do is record 220 ; that we need to make the call later, which we'll do from un.onGUIEnd. 221 StrCpy $ShouldOpenSurvey "1" 222 FunctionEnd 223 224 ; This function is used to uninstall the maintenance service if the 225 ; application currently being uninstalled is the last application to use the 226 ; maintenance service. 227 Function un.UninstallServiceIfNotUsed 228 ; $0 will store if a subkey exists 229 ; $1 will store the first subkey if it exists or an empty string if it doesn't 230 ; Backup the old values 231 Push $0 232 Push $1 233 234 ; The maintenance service always uses the 64-bit registry on x64 systems 235 ${If} ${RunningX64} 236 ${OrIf} ${IsNativeARM64} 237 SetRegView 64 238 ${EndIf} 239 240 ; Figure out the number of subkeys 241 StrCpy $0 0 242 ${Do} 243 EnumRegKey $1 HKLM "Software\Mozilla\MaintenanceService" $0 244 ${If} "$1" == "" 245 ${ExitDo} 246 ${EndIf} 247 IntOp $0 $0 + 1 248 ${Loop} 249 250 ; Restore back the registry view 251 ${If} ${RunningX64} 252 ${OrIf} ${IsNativeARM64} 253 SetRegView lastused 254 ${EndIf} 255 256 ${If} $0 == 0 257 ; Get the path of the maintenance service uninstaller. 258 ; Look in both the 32-bit and 64-bit registry views. 259 SetRegView 32 260 ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString" 261 SetRegView lastused 262 263 ${If} ${RunningX64} 264 ${OrIf} ${IsNativeARM64} 265 ${If} $1 == "" 266 SetRegView 64 267 ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString" 268 SetRegView lastused 269 ${EndIf} 270 ${EndIf} 271 272 ; If the uninstall string does not exist, skip executing it 273 ${If} $1 != "" 274 ; $1 is already a quoted string pointing to the install path 275 ; so we're already protected against paths with spaces 276 nsExec::Exec "$1 /S" 277 ${EndIf} 278 ${EndIf} 279 280 ; Restore the old value of $1 and $0 281 Pop $1 282 Pop $0 283 FunctionEnd 284 285 Function un.LaunchAppForRefresh 286 Push $0 287 Push $1 288 ; Set the current working directory to the installation directory 289 SetOutPath "$INSTDIR" 290 ClearErrors 291 ${GetParameters} $0 292 ${GetOptions} "$0" "/UAC:" $1 293 ${If} ${Errors} 294 ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" ${ArgsProfileRefresh}" 295 ${Else} 296 GetFunctionAddress $0 un.LaunchAppForRefreshFromElevatedProcess 297 UAC::ExecCodeSegment $0 298 ${EndIf} 299 Pop $1 300 Pop $0 301 FunctionEnd 302 303 Function un.LaunchAppForRefreshFromElevatedProcess 304 ; Set the current working directory to the installation directory 305 SetOutPath "$INSTDIR" 306 ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" ${ArgsProfileRefresh}" 307 FunctionEnd 308 309 Function un.LaunchRefreshHelpPage 310 Push $0 311 Push $1 312 ClearErrors 313 ${GetParameters} $0 314 ${GetOptions} "$0" "/UAC:" $1 315 ${If} ${Errors} 316 Call un.OpenRefreshHelpURL 317 ${Else} 318 GetFunctionAddress $0 un.OpenRefreshHelpURL 319 UAC::ExecCodeSegment $0 320 ${EndIf} 321 Pop $1 322 Pop $0 323 FunctionEnd 324 325 Function un.OpenRefreshHelpURL 326 ExecShell "open" "${URLProfileRefreshHelp}" 327 FunctionEnd 328 329 Function un.SendUninstallPing 330 ; Notably, we only check the non-private AUMID here. There's no good reason 331 ; to send the uninstall ping twice. 332 ${If} $AppUserModelID == "" 333 Return 334 ${EndIf} 335 336 Push $0 ; $0 = Find handle 337 Push $1 ; $1 = Found ping file name 338 Push $2 ; $2 = Directory containing the pings 339 Push $3 ; $3 = Ping file name filespec 340 Push $4 ; $4 = Offset of ID in file name 341 Push $5 ; $5 = URL, POST result 342 Push $6 ; $6 = Full path to the ping file 343 344 Call un.GetCommonDirectory 345 Pop $2 346 347 ; The ping ID is in the file name, so that we can get it for the submission URL 348 ; without having to parse the ping. Since we don't know the exact name, use FindFirst 349 ; to locate the file. 350 ; Format is uninstall_ping_$AppUserModelID_$PingUUID.json 351 352 ; File name base 353 StrCpy $3 "uninstall_ping_$AppUserModelID_" 354 ; Get length of the fixed prefix, this is the offset of ping ID in the file name 355 StrLen $4 $3 356 ; Finish building filespec 357 StrCpy $3 "$2\$3*.json" 358 359 ClearErrors 360 FindFirst $0 $1 $3 361 ; Build the full path 362 StrCpy $6 "$2\$1" 363 364 ${IfNot} ${Errors} 365 ; Copy the ping ID, starting after $AppUserModelID_, ending 5 from the end to remove .json 366 StrCpy $5 $1 -5 $4 367 368 ; Build the full submission URL from the ID 369 ; https://docs.telemetry.mozilla.org/concepts/pipeline/http_edge_spec.html#special-handling-for-firefox-desktop-telemetry 370 ; It's possible for the path components to disagree with the contents of the ping, 371 ; but this should be rare, and shouldn't affect the collection. 372 StrCpy $5 "${TELEMETRY_BASE_URL}/${TELEMETRY_UNINSTALL_PING_NAMESPACE}/$5/${TELEMETRY_UNINSTALL_PING_DOCTYPE}/${AppName}/$InstalledVersion/${UpdateChannel}/$InstalledBuildID?v=4" 373 374 HttpPostFile::Post $6 "Content-Type: application/json$\r$\n" $5 375 ; Pop the result. This could indicate an error if it's something other than 376 ; "success", but we don't have any recovery path here anyway. 377 Pop $5 378 379 ${Do} 380 Delete $6 381 382 ; Continue to delete any other pings from this install. Only the first found will be sent: 383 ; there should only be one ping, if there are more than one then something has gone wrong, 384 ; it seems preferable to not try to send them all. 385 ClearErrors 386 FindNext $0 $1 387 ; Build the full path 388 StrCpy $6 "$2\$1" 389 ${LoopUntil} ${Errors} 390 391 FindClose $0 392 ${Endif} 393 394 Pop $6 395 Pop $5 396 Pop $4 397 Pop $3 398 Pop $2 399 Pop $1 400 Pop $0 401 FunctionEnd 402 403 ################################################################################ 404 # Install Sections 405 ; Empty section required for the installer to compile as an uninstaller 406 Section "" 407 SectionEnd 408 409 ################################################################################ 410 # Uninstall Sections 411 412 Section "Uninstall" 413 SetDetailsPrint textonly 414 DetailPrint $(STATUS_UNINSTALL_MAIN) 415 SetDetailsPrint none 416 417 ; Some system cleanup is most easily handled when XPCOM functionality is 418 ; available - e.g. removing notifications from Window's Action Center. We 419 ; handle this in the `uninstall` background task. 420 ; 421 ; Return value is saved to an unused variable to prevent the the error flag 422 ; from being set. 423 Var /GLOBAL UnusedExecCatchReturn 424 ExecWait '"$INSTDIR\${FileMainEXE}" --backgroundtask uninstall' $UnusedExecCatchReturn 425 426 ; Uninstall the default browser agent scheduled task and all other scheduled 427 ; tasks registered by Firefox. 428 ; This also removes the registry entries that the WDBA creates. 429 ; One of the scheduled tasks that this will remove is the Background Update 430 ; Task. Ideally, this will eventually be changed so that it doesn't rely on 431 ; the WDBA. See Bug 1710143. 432 ExecWait '"$INSTDIR\default-browser-agent.exe" uninstall $AppUserModelID' 433 ${RemoveDefaultBrowserAgentShortcut} 434 435 ; Delete the app exe to prevent launching the app while we are uninstalling. 436 ClearErrors 437 ${DeleteFile} "$INSTDIR\${FileMainEXE}" 438 ${If} ${Errors} 439 ; If the user closed the application it can take several seconds for it to 440 ; shut down completely. If the application is being used by another user we 441 ; can still delete the files when the system is restarted. 442 Sleep 5000 443 ${DeleteFile} "$INSTDIR\${FileMainEXE}" 444 ClearErrors 445 ${EndIf} 446 447 ReadRegDWORD $R4 HKCU "Software\Mozilla\${BrandFullNameInternal}" DesktopLauncherAppInstalled 448 ${IfNot} ${Errors} 449 ${AndIf} $R4 == "1" 450 ; The current user had a desktop launcher at some point, so remove it. 451 SetShellVarContext current 452 Delete "$DESKTOP\${BrandShortName}.exe" 453 ${IfNot} ${Errors} 454 DeleteRegValue HKCU "Software\Mozilla\${BrandFullNameInternal}" DesktopLauncherAppInstalled 455 ${EndIf} 456 ${EndIf} 457 ClearErrors 458 459 SetShellVarContext current ; Set SHCTX to HKCU 460 ${un.RegCleanMain} "Software\Mozilla" 461 ${un.RegCleanPrefs} "Software\Mozilla\${AppName}" 462 ${un.RegCleanUninstall} 463 ${un.DeleteShortcuts} 464 465 ${If} "$AppUserModelID" != "" 466 ; Unregister resources associated with taskbar jump lists. 467 ApplicationID::UninstallJumpLists "$AppUserModelID" 468 ; Remove the update sync manager's multi-instance lock file 469 Call un.GetCommonDirectory 470 Pop $0 471 Delete /REBOOTOK "$0\UpdateLock-$AppUserModelID" 472 ${EndIf} 473 474 ${If} "$AppUserModelIDPrivate" != "" 475 ApplicationID::UninstallJumpLists "$AppUserModelIDPrivate" 476 ${EndIf} 477 478 ; Clean up old maintenance service logs 479 ${un.CleanMaintenanceServiceLogs} "Mozilla\Firefox" 480 481 ; Remove any app model id's stored in the registry for this install path 482 DeleteRegValue HKCU "Software\Mozilla\${AppName}\TaskBarIDs" "$INSTDIR" 483 DeleteRegValue HKLM "Software\Mozilla\${AppName}\TaskBarIDs" "$INSTDIR" 484 485 ClearErrors 486 WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" 487 ${If} ${Errors} 488 StrCpy $RegHive "HKCU" 489 ${Else} 490 SetShellVarContext all ; Set SHCTX to HKLM 491 DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" 492 StrCpy $RegHive "HKLM" 493 ${un.RegCleanMain} "Software\Mozilla" 494 ${un.RegCleanUninstall} 495 ${un.DeleteShortcuts} 496 ${un.SetAppLSPCategories} 497 ${EndIf} 498 499 ${un.RegCleanAppHandler} "FirefoxHTML-$AppUserModelID" 500 ${un.RegCleanAppHandler} "FirefoxPDF-$AppUserModelID" 501 ${un.RegCleanAppHandler} "FirefoxURL-$AppUserModelID" 502 ${un.RegCleanProtocolHandler} "http" 503 ${un.RegCleanProtocolHandler} "https" 504 ${un.RegCleanProtocolHandler} "mailto" 505 ${un.RegCleanFileHandler} ".htm" "FirefoxHTML-$AppUserModelID" 506 ${un.RegCleanFileHandler} ".html" "FirefoxHTML-$AppUserModelID" 507 ${un.RegCleanFileHandler} ".shtml" "FirefoxHTML-$AppUserModelID" 508 ${un.RegCleanFileHandler} ".xht" "FirefoxHTML-$AppUserModelID" 509 ${un.RegCleanFileHandler} ".xhtml" "FirefoxHTML-$AppUserModelID" 510 ${un.RegCleanFileHandler} ".oga" "FirefoxHTML-$AppUserModelID" 511 ${un.RegCleanFileHandler} ".ogg" "FirefoxHTML-$AppUserModelID" 512 ${un.RegCleanFileHandler} ".ogv" "FirefoxHTML-$AppUserModelID" 513 ${un.RegCleanFileHandler} ".webm" "FirefoxHTML-$AppUserModelID" 514 ${un.RegCleanFileHandler} ".svg" "FirefoxHTML-$AppUserModelID" 515 ${un.RegCleanFileHandler} ".webp" "FirefoxHTML-$AppUserModelID" 516 ${un.RegCleanFileHandler} ".avif" "FirefoxHTML-$AppUserModelID" 517 518 ${un.RegCleanFileHandler} ".pdf" "FirefoxPDF-$AppUserModelID" 519 520 SetShellVarContext all ; Set SHCTX to HKLM 521 ${un.GetSecondInstallPath} "Software\Mozilla" $R9 522 ${If} $R9 == "false" 523 SetShellVarContext current ; Set SHCTX to HKCU 524 ${un.GetSecondInstallPath} "Software\Mozilla" $R9 525 ${EndIf} 526 527 DeleteRegKey HKLM "Software\Clients\StartMenuInternet\${AppRegName}-$AppUserModelID" 528 DeleteRegValue HKLM "Software\RegisteredApplications" "${AppRegName}-$AppUserModelID" 529 530 DeleteRegKey HKCU "Software\Clients\StartMenuInternet\${AppRegName}-$AppUserModelID" 531 DeleteRegValue HKCU "Software\RegisteredApplications" "${AppRegName}-$AppUserModelID" 532 533 ; Clean up "launch on login" registry key for this installation. 534 DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "Mozilla-${AppName}-$AppUserModelID" 535 536 ; Remove FirefoxBridge extension protocol handlers 537 Push $1 538 ${un.GetLongPath} "$INSTDIR\${FileMainEXE}" $1 539 ${DeleteProtocolRegistryIfSetToInstallation} "$1" "firefox-bridge" 540 ${DeleteProtocolRegistryIfSetToInstallation} "$1" "firefox-private-bridge" 541 Pop $1 542 543 ; Remove old protocol handler and StartMenuInternet keys without install path 544 ; hashes, but only if they're for this installation. We've never supported 545 ; bare FirefoxPDF. 546 ReadRegStr $0 HKLM "Software\Classes\FirefoxHTML\DefaultIcon" "" 547 StrCpy $0 $0 -2 548 ${If} $0 == "$INSTDIR\${FileMainEXE}" 549 DeleteRegKey HKLM "Software\Classes\FirefoxHTML" 550 DeleteRegKey HKLM "Software\Classes\FirefoxURL" 551 ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 552 DeleteRegKey HKLM "Software\Clients\StartMenuInternet\$R9" 553 DeleteRegValue HKLM "Software\RegisteredApplications" "$R9" 554 DeleteRegValue HKLM "Software\RegisteredApplications" "${AppRegName}" 555 ${EndIf} 556 ReadRegStr $0 HKCU "Software\Classes\FirefoxHTML\DefaultIcon" "" 557 StrCpy $0 $0 -2 558 ${If} $0 == "$INSTDIR\${FileMainEXE}" 559 DeleteRegKey HKCU "Software\Classes\FirefoxHTML" 560 DeleteRegKey HKCU "Software\Classes\FirefoxURL" 561 ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 562 DeleteRegKey HKCU "Software\Clients\StartMenuInternet\$R9" 563 DeleteRegValue HKCU "Software\RegisteredApplications" "$R9" 564 DeleteRegValue HKCU "Software\RegisteredApplications" "${AppRegName}" 565 ${EndIf} 566 567 StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\App Paths\${FileMainEXE}" 568 ${If} $R9 == "false" 569 DeleteRegKey HKLM "$0" 570 DeleteRegKey HKCU "$0" 571 StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\${FileMainEXE}" 572 DeleteRegKey HKLM "$0" 573 DeleteRegKey HKCU "$0" 574 StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe" 575 DeleteRegKey HKLM "$0" 576 DeleteRegKey HKCU "$0" 577 StrCpy $0 "Software\Classes\MIME\Database\Content Type\application/x-xpinstall;app=firefox" 578 DeleteRegKey HKLM "$0" 579 DeleteRegKey HKCU "$0" 580 ${Else} 581 ReadRegStr $R1 HKLM "$0" "" 582 ${un.RemoveQuotesFromPath} "$R1" $R1 583 ${un.GetParent} "$R1" $R1 584 ${If} "$INSTDIR" == "$R1" 585 WriteRegStr HKLM "$0" "" "$R9" 586 ${un.GetParent} "$R9" $R1 587 WriteRegStr HKLM "$0" "Path" "$R1" 588 ${EndIf} 589 ${EndIf} 590 591 ; Remove our HKCR/Applications key, if it's for this installation. 592 ReadRegStr $0 HKLM "Software\Classes\Applications\${FileMainEXE}\DefaultIcon" "" 593 StrCpy $0 $0 -2 594 ${If} $0 == "$INSTDIR\${FileMainEXE}" 595 DeleteRegKey HKLM "Software\Classes\Applications\${FileMainEXE}" 596 ${EndIf} 597 ReadRegStr $0 HKCU "Software\Classes\Applications\${FileMainEXE}\DefaultIcon" "" 598 StrCpy $0 $0 -2 599 ${If} $0 == "$INSTDIR\${FileMainEXE}" 600 DeleteRegKey HKCU "Software\Classes\Applications\${FileMainEXE}" 601 ${EndIf} 602 603 ; Remove directories and files we always control before parsing the uninstall 604 ; log so empty directories can be removed. 605 ${If} ${FileExists} "$INSTDIR\updates" 606 RmDir /r /REBOOTOK "$INSTDIR\updates" 607 ${EndIf} 608 ${If} ${FileExists} "$INSTDIR\updated" 609 RmDir /r /REBOOTOK "$INSTDIR\updated" 610 ${EndIf} 611 ${If} ${FileExists} "$INSTDIR\defaults\shortcuts" 612 RmDir /r /REBOOTOK "$INSTDIR\defaults\shortcuts" 613 ${EndIf} 614 ${If} ${FileExists} "$INSTDIR\distribution" 615 RmDir /r /REBOOTOK "$INSTDIR\distribution" 616 ${EndIf} 617 618 ; Remove files that may be left behind by the application in the 619 ; VirtualStore directory. 620 ${un.CleanVirtualStore} 621 622 ; Only unregister the dll if the registration points to this installation 623 ReadRegStr $R1 HKCR "CLSID\{0D68D6D0-D93D-4D08-A30D-F00DD1F45B24}\InProcServer32" "" 624 ${If} "$INSTDIR\AccessibleMarshal.dll" == "$R1" 625 ${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll" 626 ${EndIf} 627 628 ${If} ${FileExists} "$INSTDIR\AccessibleHandler.dll" 629 ${UnregisterDLL} "$INSTDIR\AccessibleHandler.dll" 630 ${EndIf} 631 632 ; Remove the Windows Reporter Module entry 633 DeleteRegValue HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" "$INSTDIR\mozwer.dll" 634 635 !ifdef MOZ_LAUNCHER_PROCESS 636 DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Launcher" 637 DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Browser" 638 DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Image" 639 DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Telemetry" 640 !endif 641 642 ; Remove Toast Notification registration. 643 ; Find any GUID used for this installation. 644 ClearErrors 645 ReadRegStr $0 HKLM "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator" 646 647 DeleteRegValue HKLM "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator" 648 DeleteRegValue HKLM "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "DisplayName" 649 DeleteRegValue HKLM "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "IconUri" 650 DeleteRegKey HKLM "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" 651 ${If} "$0" != "" 652 DeleteRegValue HKLM "Software\Classes\AppID\$0" "DllSurrogate" 653 DeleteRegKey HKLM "Software\Classes\AppID\$0" 654 DeleteRegValue HKLM "Software\Classes\CLSID\$0" "AppID" 655 DeleteRegValue HKLM "Software\Classes\CLSID\$0\InProcServer32" "" 656 DeleteRegKey HKLM "Software\Classes\CLSID\$0\InProcServer32" 657 DeleteRegKey HKLM "Software\Classes\CLSID\$0" 658 ${EndIf} 659 660 ClearErrors 661 ReadRegStr $0 HKCU "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator" 662 663 DeleteRegValue HKCU "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator" 664 DeleteRegValue HKCU "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "DisplayName" 665 DeleteRegValue HKCU "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "IconUri" 666 DeleteRegKey HKCU "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" 667 ${If} "$0" != "" 668 DeleteRegValue HKCU "Software\Classes\AppID\$0" "DllSurrogate" 669 DeleteRegKey HKCU "Software\Classes\AppID\$0" 670 DeleteRegValue HKCU "Software\Classes\CLSID\$0" "AppID" 671 DeleteRegValue HKCU "Software\Classes\CLSID\$0\InProcServer32" "" 672 DeleteRegKey HKCU "Software\Classes\CLSID\$0\InProcServer32" 673 DeleteRegKey HKCU "Software\Classes\CLSID\$0" 674 ${EndIf} 675 676 ${un.RemovePrecompleteEntries} "false" 677 678 ${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js" 679 Delete /REBOOTOK "$INSTDIR\defaults\pref\channel-prefs.js" 680 ${EndIf} 681 RmDir "$INSTDIR\defaults\pref" 682 RmDir "$INSTDIR\defaults" 683 ${If} ${FileExists} "$INSTDIR\uninstall" 684 ; Remove the uninstall directory that we control 685 RmDir /r /REBOOTOK "$INSTDIR\uninstall" 686 ${EndIf} 687 ${If} ${FileExists} "$INSTDIR\install.log" 688 Delete /REBOOTOK "$INSTDIR\install.log" 689 ${EndIf} 690 ${If} ${FileExists} "$INSTDIR\update-settings.ini" 691 Delete /REBOOTOK "$INSTDIR\update-settings.ini" 692 ${EndIf} 693 ${If} ${FileExists} "$INSTDIR\installation_telemetry.json" 694 Delete /REBOOTOK "$INSTDIR\installation_telemetry.json" 695 ${EndIf} 696 ${If} ${FileExists} "$INSTDIR\postSigningData" 697 Delete /REBOOTOK "$INSTDIR\postSigningData" 698 ${EndIf} 699 700 ; Explicitly remove empty webapprt dir in case it exists (bug 757978). 701 RmDir "$INSTDIR\webapprt\components" 702 RmDir "$INSTDIR\webapprt" 703 704 ; Remove the installation directory if it is empty 705 RmDir "$INSTDIR" 706 707 ; If firefox.exe was successfully deleted yet we still need to restart to 708 ; remove other files create a dummy firefox.exe.moz-delete to prevent the 709 ; installer from allowing an install without restart when it is required 710 ; to complete an uninstall. 711 ${If} ${RebootFlag} 712 ; Admin is required to delete files on reboot so only add the moz-delete if 713 ; the user is an admin. After calling UAC::IsAdmin $0 will equal 1 if the 714 ; user is an admin. 715 UAC::IsAdmin 716 ${If} "$0" == "1" 717 ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-delete" 718 FileOpen $0 "$INSTDIR\${FileMainEXE}.moz-delete" w 719 FileWrite $0 "Will be deleted on restart" 720 Delete /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-delete" 721 FileClose $0 722 ${EndUnless} 723 ${EndIf} 724 ${EndIf} 725 726 ; Refresh desktop icons otherwise the start menu internet item won't be 727 ; removed and other ugly things will happen like recreation of the app's 728 ; clients registry key by the OS under some conditions. 729 ${RefreshShellIcons} 730 731 ; Users who uninstall then reinstall expecting Firefox to use a clean profile 732 ; may be surprised during first-run. This key is checked during startup of Firefox and 733 ; subsequently deleted after checking. If the value is found during startup 734 ; the browser will offer to Reset Firefox. We use the UpdateChannel to match 735 ; uninstalls of Firefox-release with reinstalls of Firefox-release, for example. 736 WriteRegStr HKCU "Software\Mozilla\Firefox" "Uninstalled-${UpdateChannel}" "True" 737 738 !ifdef MOZ_MAINTENANCE_SERVICE 739 ; Get the path the allowed cert is at and remove it 740 ; Keep this block of code last since it modfies the reg view 741 ServicesHelper::PathToUniqueRegistryPath "$INSTDIR" 742 Pop $MaintCertKey 743 ${If} $MaintCertKey != "" 744 ; Always use the 64bit registry for certs on 64bit systems. 745 ${If} ${RunningX64} 746 ${OrIf} ${IsNativeARM64} 747 SetRegView 64 748 ${EndIf} 749 DeleteRegKey HKLM "$MaintCertKey" 750 ${If} ${RunningX64} 751 ${OrIf} ${IsNativeARM64} 752 SetRegView lastused 753 ${EndIf} 754 ${EndIf} 755 Call un.UninstallServiceIfNotUsed 756 !endif 757 758 !ifdef MOZ_BITS_DOWNLOAD 759 BitsUtils::CancelBitsJobsByName "MozillaUpdate $AppUserModelID" 760 Pop $0 761 !endif 762 763 ${un.IsFirewallSvcRunning} 764 Pop $0 765 ${If} "$0" == "true" 766 liteFirewallW::RemoveRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)" 767 ${EndIf} 768 SectionEnd 769 770 ################################################################################ 771 # Language 772 773 !insertmacro MOZ_MUI_LANGUAGE 'baseLocale' 774 !verbose push 775 !verbose 3 776 !include "overrideLocale.nsh" 777 !include "customLocale.nsh" 778 !verbose pop 779 780 ; Set this after the locale files to override it if it is in the locale. Using 781 ; " " for BrandingText will hide the "Nullsoft Install System..." branding. 782 BrandingText " " 783 784 ################################################################################ 785 # Page pre, show, and leave functions 786 787 Function un.preWelcome 788 ${If} ${FileExists} "$INSTDIR\distribution\modern-wizard.bmp" 789 Delete "$PLUGINSDIR\modern-wizard.bmp" 790 CopyFiles /SILENT "$INSTDIR\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp" 791 ${EndIf} 792 !ifdef MOZ_BITS_DOWNLOAD 793 BitsUtils::StartBitsServiceBackground 794 !endif 795 796 ; We don't want the header bitmap showing on the welcome page. 797 GetDlgItem $0 $HWNDPARENT 1046 798 ShowWindow $0 ${SW_HIDE} 799 800 ${If} $ShouldPromptForRefresh == "1" 801 ; Note: INI strings added here (rather than overwriting an existing value) 802 ; should be removed in un.leaveWelcome, since ioSpecial.ini is reused 803 ; for the Finish page. 804 805 ; Replace title and body text 806 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 2" Text "$(UN_REFRESH_PAGE_TITLE)" 807 ; Convert to translate newlines, this includes $PLUGINSDIR internally. 808 !insertmacro INSTALLOPTIONS_WRITE_UNCONVERT "ioSpecial.ini" "Field 3" Text "$(UN_REFRESH_PAGE_EXPLANATION)" 809 810 ; Make room for the link and button 811 StrCpy $0 "148" 812 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 3" Bottom $0 813 814 ; Show the help link 815 IntOp $1 $0 + 14 816 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Type "link" 817 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Text "$(UN_REFRESH_LEARN_MORE)" 818 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Left "120" 819 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Top $0 820 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Right "315" 821 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Bottom $1 822 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Flags "NOTIFY" 823 824 ; Show the refresh button. 825 IntOp $2 $1 + 14 826 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Type "button" 827 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Text "$(UN_REFRESH_BUTTON)" 828 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Left "120" 829 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Top $1 830 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Right "240" 831 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Bottom $2 832 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 5" Flags "NOTIFY" 833 834 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Settings" NumFields 5 835 ${EndIf} 836 FunctionEnd 837 838 Function un.ShowWelcome 839 ; The welcome and finish pages don't get the correct colors for their labels 840 ; like the other pages do, presumably because they're built by filling in an 841 ; InstallOptions .ini file instead of from a dialog resource like the others. 842 ; Field 2 is the header and Field 3 is the body text. 843 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 2" "HWND" 844 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 845 846 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 3" "HWND" 847 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 848 849 ${If} $ShouldPromptForRefresh == "1" 850 ; Field 4 is the profile refresh help link 851 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 4" "HWND" 852 SetCtlColors $0 SYSCLR:HOTLIGHT SYSCLR:WINDOW 853 ${EndIf} 854 855 ; We need to overwrite the sidebar image so that we get it drawn with proper 856 ; scaling if the display is scaled at anything above 100%. 857 ${un.ChangeMUISidebarImage} "$PLUGINSDIR\modern-wizard.bmp" 858 FunctionEnd 859 860 Function un.leaveWelcome 861 StrCpy $RefreshRequested "0" 862 863 ${If} $ShouldPromptForRefresh == "1" 864 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Settings" "State" 865 ${If} $0 == "5" 866 ; Refresh button 867 StrCpy $RefreshRequested "1" 868 ${ElseIf} $0 == "4" 869 ; Launch refresh help link, stay on this page 870 Call un.LaunchRefreshHelpPage 871 Abort 872 ${EndIf} 873 ${EndIf} 874 875 ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" 876 Banner::show /NOUNLOAD "$(BANNER_CHECK_EXISTING)" 877 878 ; If we already found a window once and we're checking again, wait for an 879 ; additional five seconds for the app to close. 880 ${If} "$TmpVal" == "FoundAppWindow" 881 Sleep 5000 882 ${EndIf} 883 884 ${PushFilesToCheck} 885 886 ${un.CheckForFilesInUse} $TmpVal 887 888 Banner::destroy 889 890 ; If there are files in use $TmpVal will be "true" 891 ${If} "$TmpVal" == "true" 892 ; If it finds a window of the right class, then ManualCloseAppPrompt will 893 ; abort leaving the value of $TmpVal set to "FoundAppWindow". 894 StrCpy $TmpVal "FoundAppWindow" 895 896 ${If} $RefreshRequested == "1" 897 ${un.ManualCloseAppPrompt} "${MainWindowClass}" "$(WARN_MANUALLY_CLOSE_APP_REFRESH)" 898 ${un.ManualCloseAppPrompt} "${DialogWindowClass}" "$(WARN_MANUALLY_CLOSE_APP_REFRESH)" 899 ${Else} 900 ${un.ManualCloseAppPrompt} "${MainWindowClass}" "$(WARN_MANUALLY_CLOSE_APP_UNINSTALL)" 901 ${un.ManualCloseAppPrompt} "${DialogWindowClass}" "$(WARN_MANUALLY_CLOSE_APP_UNINSTALL)" 902 ${EndIf} 903 ; If the message window is not found set $TmpVal to "true" so the restart 904 ; required message is displayed. 905 ; In the case of a refresh request the restart required message will not be displayed; 906 ; we're not trying to change the installation, so files in use only matter if the 907 ; window is shown. 908 StrCpy $TmpVal "true" 909 ${EndIf} 910 ${EndIf} 911 912 ${If} $RefreshRequested == "1" 913 Call un.LaunchAppForRefresh 914 Quit 915 ${EndIf} 916 917 ${If} $ShouldPromptForRefresh == "1" 918 ; Remove the custom controls. 919 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Settings" NumFields 3 920 DeleteIniSec "$PLUGINSDIR\ioSpecial.ini" "Field 4" 921 DeleteIniSec "$PLUGINSDIR\ioSpecial.ini" "Field 5" 922 ${EndIf} 923 924 ; Bring back the header bitmap for the next pages. 925 GetDlgItem $0 $HWNDPARENT 1046 926 ShowWindow $0 ${SW_SHOW} 927 FunctionEnd 928 929 Function un.preConfirm 930 ; The header on the wizard pages doesn't get the correct text 931 ; color by default for some reason, even though the other controls do. 932 GetDlgItem $0 $HWNDPARENT 1037 933 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 934 ; Hide unused subheader (to avoid overlapping moved header) 935 GetDlgItem $0 $HWNDPARENT 1038 936 ShowWindow $0 ${SW_HIDE} 937 938 ${If} ${FileExists} "$INSTDIR\distribution\modern-header.bmp" 939 Delete "$PLUGINSDIR\modern-header.bmp" 940 CopyFiles /SILENT "$INSTDIR\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp" 941 ${EndIf} 942 ${un.ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp" 943 944 ; Setup the unconfirm.ini file for the Custom Uninstall Confirm Page 945 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "3" 946 947 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Type "label" 948 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Text "$(UN_CONFIRM_UNINSTALLED_FROM)" 949 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Left "0" 950 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Right "-1" 951 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Top "5" 952 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Bottom "15" 953 954 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Type "text" 955 ; The contents of this control must be set as follows in the pre function 956 ; ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND" 957 ; SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR" 958 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" State "" 959 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Left "0" 960 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Right "-1" 961 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Top "17" 962 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Bottom "30" 963 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" flags "READONLY" 964 965 ${If} "$TmpVal" == "true" 966 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Type "label" 967 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Text "$(SUMMARY_REBOOT_REQUIRED_UNINSTALL)" 968 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Left "0" 969 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Right "-1" 970 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Top "35" 971 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Bottom "45" 972 973 WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "3" 974 ${EndIf} 975 976 !insertmacro MUI_HEADER_TEXT "$(UN_CONFIRM_PAGE_TITLE)" "" 977 978 ; The Summary custom page has a textbox that will automatically receive 979 ; focus. This sets the focus to the Install button instead. 980 !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini" 981 GetDlgItem $0 $HWNDPARENT 1 982 System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i" 983 ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND" 984 SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR" 985 !insertmacro MUI_INSTALLOPTIONS_SHOW 986 FunctionEnd 987 988 Function un.onUninstSuccess 989 ; Send a ping at un.onGUIEnd, to avoid freezing the GUI. 990 StrCpy $ShouldSendPing "1" 991 992 ${If} ${Silent} 993 ; If this is a silent uninstall then un.onGUIEnd doesn't run, so do it now. 994 Call un.SendUninstallPing 995 ${EndIf} 996 FunctionEnd 997 998 Function un.preFinish 999 ; Need to give the survey (readme) checkbox a few extra DU's of height 1000 ; to accommodate a potentially multi-line label. If the reboot flag is set, 1001 ; then we're not showing the survey checkbox and Field 4 is the "reboot now" 1002 ; radio button; setting it to go from 90 to 120 (instead of 90 to 100) would 1003 ; cover up Field 5 which is "reboot later", running from 110 to 120. For 1004 ; whatever reason child windows get created at the bottom of the z-order, so 1005 ; 4 overlaps 5. 1006 ${IfNot} ${RebootFlag} 1007 WriteINIStr "$PLUGINSDIR\ioSpecial.ini" "Field 4" Bottom "120" 1008 ${EndIf} 1009 1010 ; We don't want the header bitmap showing on the finish page. 1011 GetDlgItem $0 $HWNDPARENT 1046 1012 ShowWindow $0 ${SW_HIDE} 1013 FunctionEnd 1014 1015 Function un.ShowFinish 1016 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 2" "HWND" 1017 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 1018 1019 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 3" "HWND" 1020 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 1021 1022 ; We need to overwrite the sidebar image so that we get it drawn with proper 1023 ; scaling if the display is scaled at anything above 100%. 1024 ${un.ChangeMUISidebarImage} "$PLUGINSDIR\modern-wizard.bmp" 1025 1026 ; Either Fields 4 and 5 are the reboot option radio buttons, or Field 4 is 1027 ; the survey checkbox and Field 5 doesn't exist. Either way, we need to 1028 ; clear the theme from them before we can set their background colors. 1029 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 4" "HWND" 1030 System::Call 'uxtheme::SetWindowTheme(i $0, w " ", w " ")' 1031 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 1032 1033 ClearErrors 1034 ReadINIStr $0 "$PLUGINSDIR\ioSpecial.ini" "Field 5" "HWND" 1035 ${IfNot} ${Errors} 1036 System::Call 'uxtheme::SetWindowTheme(i $0, w " ", w " ")' 1037 SetCtlColors $0 SYSCLR:WINDOWTEXT SYSCLR:WINDOW 1038 ${EndIf} 1039 FunctionEnd 1040 1041 ################################################################################ 1042 # Initialization Functions 1043 1044 Function .onInit 1045 ; Remove the current exe directory from the search order. 1046 ; This only effects LoadLibrary calls and not implicitly loaded DLLs. 1047 System::Call 'kernel32::SetDllDirectoryW(w "")' 1048 1049 ; We need this set up for most of the helper.exe operations. 1050 ${UninstallOnInitCommon} 1051 FunctionEnd 1052 1053 Function un.onInit 1054 ; Remove the current exe directory from the search order. 1055 ; This only effects LoadLibrary calls and not implicitly loaded DLLs. 1056 System::Call 'kernel32::SetDllDirectoryW(w "")' 1057 1058 StrCpy $LANGUAGE 0 1059 StrCpy $ShouldOpenSurvey "0" 1060 1061 ${un.UninstallUnOnInitCommon} 1062 1063 ; setup the application model id registration value 1064 ${un.InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" 1065 1066 ; Find a default profile for this install. 1067 SetShellVarContext current 1068 ${un.FindInstallSpecificProfile} 1069 Pop $1 1070 GetFullPathName $1 $1 1071 1072 ; If there is an existing default profile, offer profile refresh. 1073 StrCpy $ShouldPromptForRefresh "0" 1074 StrCpy $RefreshRequested "0" 1075 ${If} $1 != "" 1076 StrCpy $ShouldPromptForRefresh "1" 1077 ${EndIf} 1078 1079 ; Load version info for uninstall ping (sent after uninstall is complete) 1080 ReadINIStr $InstalledVersion "$INSTDIR\application.ini" "App" "Version" 1081 ReadINIStr $InstalledBuildID "$INSTDIR\application.ini" "App" "BuildID" 1082 1083 !insertmacro InitInstallOptionsFile "unconfirm.ini" 1084 FunctionEnd 1085 1086 Function un.GUIInit 1087 ; Move header text down, roughly vertically centered in the header. 1088 ; Even if we're not changing the X, we can't set Y without also setting X. 1089 ; Child window positions have to be set in client coordinates, and these are 1090 ; left-to-right mirrored for RTL. 1091 GetDlgItem $0 $HWNDPARENT 1037 1092 ; Get current rect in screen coordinates 1093 System::Call "*(i 0, i 0, i 0, i 0) i .r2" 1094 System::Call "user32::GetWindowRect(p $0, p $2)" 1095 ; Convert screen coordinates to client coordinates (handles RTL mirroring) 1096 System::Call "user32::MapWindowPoints(p 0, p $HWNDPARENT, p $2, i 2)" 1097 System::Call "*$2(i . r3, i . r4, i, i)" 1098 System::Free $2 1099 ; Move down 1100 ${DialogUnitsToPixels} 8 Y $1 1101 IntOp $4 $4 + $1 1102 ; Set position, 0x0015 is SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE 1103 System::Call "user32::SetWindowPos(p $0, p 0, i $3, i $4, i 0, i 0, i 0x0015)" 1104 FunctionEnd 1105 1106 Function .onGUIEnd 1107 ${OnEndCommon} 1108 FunctionEnd 1109 1110 Function un.onGUIEnd 1111 ${un.OnEndCommon} 1112 1113 ${If} $ShouldOpenSurvey == "1" 1114 ; Though these values are sometimes incorrect due to bug 444664 it happens 1115 ; so rarely it isn't worth working around it by reading the registry values. 1116 ${WinVerGetMajor} $0 1117 ${WinVerGetMinor} $1 1118 ${WinVerGetBuild} $2 1119 ${WinVerGetServicePackLevel} $3 1120 StrCpy $R1 "${URLUninstallSurvey}$0.$1.$2.$3" 1121 1122 ; We can't just open the URL normally because we are most likely running 1123 ; elevated without an unelevated process to redirect through, and we're 1124 ; not going to go around starting elevated web browsers. But to start an 1125 ; unelevated process directly from here we need a pretty nasty hack; see 1126 ; the ExecInExplorer plugin code itself for the details. 1127 ; If we were the default browser and we've now been uninstalled, we need 1128 ; to take steps to make sure the user doesn't see an "open with" dialog; 1129 ; they're helping us out by answering this survey, they don't need more 1130 ; friction. 1131 ; Windows 10 always seems to just clear the default browser, so for it 1132 ; we'll manually invoke Edge using Edge's custom URI scheme. 1133 ExecInExplorer::Exec "microsoft-edge:$R1" 1134 ${EndIf} 1135 1136 ; Finally send the ping, there's no GUI to freeze in case it is slow. 1137 ${If} $ShouldSendPing == "1" 1138 Call un.SendUninstallPing 1139 ${EndIf} 1140 FunctionEnd