NSIS: QoL changes, general cleanup, bug fixes (#3335)

Uninstaller:
- Removed dependency for AdvUninstallLog, it wasn't really used for anything.
- Remove unpacked installer files upon successful installation.

Installer:
- Remove detection code for versions prior to 1.4.
- Fix Unicode path issues.
- Fix path issues if install folder already exists.
- Remove language option.
- Fix redistributable installation issues.
- Move redistributable installation to after user proceeds with install.
This commit is contained in:
Christian Kenny 2020-05-05 15:02:07 -04:00 committed by lightningterror
parent c03b06e52f
commit d503b56e8c
7 changed files with 103 additions and 194 deletions

View File

@ -4,7 +4,7 @@
; (for the professionalism!!)
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${APP_NAME}"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© 2019 PCSX2 Dev Team"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Copyright 2019 PCSX2 Dev Team"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Installs PCSX2, a Playstation 2 Emulator for the PC."
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${APP_VERSION}"

View File

@ -2,17 +2,10 @@
; Shared Install Functions
; =======================================================================
Function .onInit
;prepare Advanced Uninstall log always within .onInit function
!insertmacro UNINSTALL.LOG_PREPARE_INSTALL
FunctionEnd
Function .onInstSuccess
; Remove unpacked files
;create/update log always within .onInstSuccess function
!insertmacro UNINSTALL.LOG_UPDATE_INSTALL
RMDir /r "$TEMP\PCSX2 ${APP_VERSION}"
FunctionEnd
@ -20,25 +13,18 @@ FunctionEnd
; Shared Uninstall Functions
; =======================================================================
; begin uninstall, could be added on top of uninstall section instead
Function un.onInit
!insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
FunctionEnd
Function un.onUninstSuccess
!insertmacro UNINSTALL.LOG_END_UNINSTALL
; And remove the various install dir(s) but only if they're clean of user content:
RMDir "$DOCUMENTS\PCSX2"
RMDir "$INSTDIR\langs"
RMDir /r "$INSTDIR\plugins"
Delete "$INSTDIR\Uninst-pcsx2.exe"
RMDir "$INSTDIR"
FunctionEnd
FunctionEnd
; =======================================================================
; Un.Installer Sections
; =======================================================================
Section "Un.Program and Plugins ${APP_NAME}"
SectionIn RO
; First thing, remove the registry entry in case uninstall doesn't complete successfully
; otherwise, pcsx2 will be "confused" if it's re-installed later.
@ -51,8 +37,6 @@ Section "Un.Program and Plugins ${APP_NAME}"
; Remove regkey generated by NSIS for uninstall functions
DeleteRegKey HKLM "${INSTDIR_REG_KEY}"
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR"
; Remove shortcuts, if any
Delete "$DESKTOP\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\${APP_NAME}.lnk"
@ -81,6 +65,7 @@ Section /o "Un.Configuration files (Programs and Plugins)"
RMDir /r "$DOCUMENTS\PCSX2\inis\"
SectionEnd
; /o for optional and unticked by default
Section /o "Un.Memory Cards and Savestates"
SetShellVarContext current
RMDir /r "$DOCUMENTS\PCSX2\memcards\"
@ -98,8 +83,6 @@ SectionEnd
; /o for optional and unticked by default
Section /o "Un.BIOS files"
SetShellVarContext current
RMDir /r "$DOCUMENTS\PCSX2\bios\"
SectionEnd

View File

@ -7,35 +7,27 @@ Function UninstallPrevious
; $needle: String to search for
; $Haystack: String to look in
; Search for 1.0.0
ReadRegStr $R7 HKLM "${INSTDIR_REG_KEY}" "Uninst-pcsx2Directory"
${StrContains} "$4" "1.0.0" "$R7"
; This will become the primary version check for 1.6.0 and later
ReadRegStr $R1 HKLM "${INSTDIR_REG_KEY}" "DisplayVersion"
ReadRegStr $R2 HKLM Software\PCSX2 "Install_Dir"
${If} $R1 != ""
${AndIf} $R2 != ""
Goto UserPrompt
${EndIf}
; Search for 1.4.0
ReadRegStr $R2 HKLM "${INSTDIR_REG_KEY}" "Uninst-pcsx2 1.4.0Directory"
${StrContains} "$2" "1.4.0" "$R2"
; Search for 1.2.1
ReadRegStr $R3 HKLM "${INSTDIR_REG_KEY}-r5875" "Uninst-pcsx2-r5875Directory"
${StrContains} "$3" "1.2.1" "$R3"
; Search for 0.9.8
ReadRegStr $R5 HKLM "${INSTDIR_REG_KEY}-r4600" "Uninst-pcsx2-r4600Directory"
${StrContains} "$5" "0.9.8" "$R5"
ReadRegStr $R3 HKLM "${INSTDIR_REG_KEY}" "Uninst-pcsx2 1.4.0Directory"
${StrContains} "$2" "1.4.0" "$R3"
; If all cases return null, our work here is done.
${If} $R2 == ""
${AndIf} $R3 == ""
${AndIf} $R5 == ""
${AndIf} $R7 == ""
Return
${EndIf}
UserPrompt:
; Installing another version
MessageBox MB_ICONEXCLAMATION|MB_OKCANCEL "Another version of PCSX2 is already installed. The current configuration folder in Documents will be duplicated and renamed as PCSX2_backup. Click OK to uninstall PCSX2 or Cancel to abort the setup." IDOK SetUninstPath IDCANCEL false
MessageBox MB_ICONEXCLAMATION|MB_OKCANCEL "An existing version of PCSX2 has been detected and will be REMOVED. The config folder in Documents will be duplicated (if it exists) and renamed as PCSX2_backup. Backup any important files and click OK to uninstall PCSX2 or Cancel to abort the setup." IDOK SetUninstPath IDCANCEL false
false:
Quit
@ -45,54 +37,27 @@ SetOutPath "$DOCUMENTS"
CopyFiles /SILENT "$DOCUMENTS\PCSX2" "$DOCUMENTS\PCSX2_backup"
RMDir /r "$DOCUMENTS\PCSX2"
${If} $R7 != ""
${AndIf} $R1 != ""
${OrIf} $4 == "1.0.0"
${If} $R1 != ""
Goto ExecNormal
${EndIf}
${If} $R2 != ""
${If} $R3 != ""
${AndIf} $2 == "1.4.0"
Goto Exec1.4.0
${EndIf}
${If} $R3 != ""
${AndIf} $3 == "1.2.1"
Goto Exec1.2.1
${EndIf}
${If} $R5 != ""
${AndIf} $5 == "0.9.8"
Goto Exec0.9.8
${EndIf}
ExecNormal:
SetOutPath "$TEMP"
CopyFiles /SILENT /FILESONLY "$R7\Uninst-pcsx2.exe" "$TEMP"
ExecWait '"$TEMP\Uninst-pcsx2.exe" /S _?=$R7'
CopyFiles /SILENT /FILESONLY "$R2\Uninst-pcsx2.exe" "$TEMP"
ExecWait '"$TEMP\Uninst-pcsx2.exe" /S _?=$R2'
Delete "$TEMP\Uninst-pcsx2.exe"
Return
Exec1.4.0:
SetOutPath "$TEMP"
CopyFiles /SILENT /FILESONLY "$R2\Uninst-pcsx2 1.4.0.exe" "$TEMP"
ExecWait '"$TEMP\Uninst-pcsx2 1.4.0.exe" /S _?=$R2'
CopyFiles /SILENT /FILESONLY "$R3\Uninst-pcsx2 1.4.0.exe" "$TEMP"
ExecWait '"$TEMP\Uninst-pcsx2 1.4.0.exe" /S _?=$R3'
Delete "$TEMP\Uninst-pcsx2 1.4.0.exe"
DeleteRegKey HKLM Software\PCSX2
Return
Exec1.2.1:
SetOutPath "$TEMP"
CopyFiles /SILENT /FILESONLY "$R3\Uninst-pcsx2-r5875.exe" "$TEMP"
ExecWait '"$TEMP\Uninst-pcsx2-r5875.exe" /S _?=$R3'
Delete "$TEMP\Uninst-pcsx2-r5875.exe"
Return
Exec0.9.8:
SetOutPath "$TEMP"
CopyFiles /SILENT /FILESONLY "$R5\Uninst-pcsx2-r4600.exe" "$TEMP"
ExecWait '"$TEMP\Uninst-pcsx2-r4600.exe" /S _?=$R5'
Delete "$TEMP\Uninst-pcsx2-r4600.exe"
Return
FunctionEnd
FunctionEnd

View File

@ -13,18 +13,40 @@
;SetShellVarContext all
;SetShellVarContext current
Section "!${APP_NAME} (required)" SEC_CORE
Function RedistInstallation
!include WinVer.nsh
SectionIn RO
; Check if the VC runtimes are installed
ReadRegDword $R5 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Installed"
CopyFiles /SILENT "$TEMP\PCSX2_installer_temp" "$INSTDIR"
CopyFiles /SILENT "$TEMP\PCSX2_installer_temp\Docs" "$INSTDIR"
CopyFiles /SILENT "$TEMP\PCSX2_installer_temp\Shaders" "$INSTDIR"
CopyFiles /SILENT "$TEMP\PCSX2_installer_temp\Plugins" "$INSTDIR"
${If} $R5 == "1"
Goto DxSetup
${EndIf}
; Download and install the VC redistributable from the internet
inetc::get /CONNECTTIMEOUT 30 /RECEIVETIMEOUT 30 "https://aka.ms/vs/16/release/VC_redist.x86.exe" "$TEMP\VC_redist.x86.exe" /END
ExecShellWait open "$TEMP\VC_redist.x86.exe" "/INSTALL /Q /NORESTART"
Delete "$TEMP\VC_redist.x86.exe"
DxSetup:
${If} ${AtLeastWin8.1}
Return
${EndIf}
; Download and install DirectX (only applies to OSes older than 8.1)
inetc::get /CONNECTTIMEOUT 30 /RECEIVETIMEOUT 30 "https://download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe" "$TEMP/dxwebsetup.exe" /END
ExecShellWait open "$TEMP\dxwebsetup.exe" "/Q"
Delete "$TEMP\dxwebsetup.exe"
FunctionEnd
Section "" SEC_REDIST
Call RedistInstallation
SectionEnd
Section "Additional Languages" SEC_LANGS
CopyFiles /SILENT "$TEMP\PCSX2_installer_temp\Langs" "$INSTDIR"
; Copy unpacked files from TEMP to the user specified directory
Section "!${APP_NAME} (required)" SEC_CORE
SectionIn RO
CopyFiles /SILENT "$TEMP\PCSX2 ${APP_VERSION}\*" "$INSTDIR\" 24000
SectionEnd
!include "SharedShortcuts.nsh"
@ -32,11 +54,9 @@ SectionEnd
LangString DESC_CORE ${LANG_ENGLISH} "Core components (binaries, plugins, documentation, etc)."
LangString DESC_STARTMENU ${LANG_ENGLISH} "Adds shortcuts for PCSX2 to the start menu (all users)."
LangString DESC_DESKTOP ${LANG_ENGLISH} "Adds a shortcut for PCSX2 to the desktop (all users)."
LangString DESC_LANGS ${LANG_ENGLISH} "Adds additional languages other than the system default to PCSX2."
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_CORE} $(DESC_CORE)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_STARTMENU} $(DESC_STARTMENU)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} $(DESC_DESKTOP)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_LANGS} $(DESC_LANGS)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

View File

@ -4,12 +4,16 @@
; This reduces duplicate code throughout both installers.
ManifestDPIAware true
Unicode true
ShowInstDetails nevershow
ShowUninstDetails nevershow
SetCompressor /SOLID lzma
SetCompressorDictSize 24
Var UserPrivileges
Var IsAdmin
!ifndef APP_VERSION
!define APP_VERSION "1.6.0"
!endif
@ -30,4 +34,32 @@ Name "${APP_NAME}"
!define MUI_HEADERIMAGE_BITMAP "banner.bmp"
!define MUI_COMPONENTSPAGE_SMALLDESC
!define MUI_ICON "AppIcon.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-uninstall.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-uninstall.ico"
Function IsUserAdmin
!include WinVer.nsh
# No user should ever have to experience this pain ;)
${IfNot} ${AtLeastWinVista}
MessageBox MB_OK "Your operating system is unsupported by PCSX2. Please upgrade your operating system or install PCSX2 1.4.0."
Quit
${EndIf}
UserInfo::GetOriginalAccountType
Pop $UserPrivileges
# GetOriginalAccountType will check the tokens of the original user of the
# current thread/process. If the user tokens were elevated or limited for
# this process, GetOriginalAccountType will return the non-restricted
# account type.
# On Vista with UAC, for example, this is not the same value when running
# with `RequestExecutionLevel user`. GetOriginalAccountType will return
# "admin" while GetAccountType will return "user".
;UserInfo::GetOriginalAccountType
;Pop $R2
${If} $UserPrivileges == "Admin"
StrCpy $IsAdmin 1
${ElseIf} $UserPrivileges == "User"
StrCpy $IsAdmin 0
${EndIf}
FunctionEnd

View File

@ -6,10 +6,8 @@
!include "SharedDefs.nsh"
RequestExecutionLevel admin
AllowRootDirInstall true
; This is the uninstaller name.
!define UNINSTALL_LOG "Uninst-pcsx2"
!define INSTDIR_REG_ROOT "HKLM"
!define OUTFILE_POSTFIX "include_standard"
@ -17,11 +15,12 @@ AllowRootDirInstall true
OutFile "pcsx2-${APP_VERSION}-${OUTFILE_POSTFIX}.exe"
; The default installation directory for the full installer
InstallDir "$PROGRAMFILES\PCSX2 ${APP_VERSION}"
InstallDir "$PROGRAMFILES\PCSX2"
!define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_FILENAME}"
!include "AdvUninstLog.nsh"
!include "StrContains.nsh"
!include "SectionVersionCheck.nsh"
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
@ -39,13 +38,9 @@ InstallDir "$PROGRAMFILES\PCSX2 ${APP_VERSION}"
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
; This defines the Advanced Uninstaller mode of operation...
!insertmacro UNATTENDED_UNINSTALL
!include "nsDialogs.nsh"
!include "ApplyExeProps.nsh"
!include "StrContains.nsh"
!include "SectionVersionCheck.nsh"
Section ""
Call UninstallPrevious
@ -64,14 +59,10 @@ Section ""
WriteRegStr HKLM "${INSTDIR_REG_KEY}" "DisplayIcon" "$INSTDIR\pcsx2.exe"
WriteRegStr HKLM "${INSTDIR_REG_KEY}" "DisplayVersion" "${APP_VERSION}"
WriteRegStr HKLM "${INSTDIR_REG_KEY}" "HelpLink" "https://forums.pcsx2.net"
${GetSize} "$INSTDIR" "/S=0K" $6 $7 $8
IntFmt $6 "0x%08X" $6
WriteRegDWORD HKLM "${INSTDIR_REG_KEY}" "EstimatedSize" "$6"
WriteRegStr HKLM "${INSTDIR_REG_KEY}" "UninstallString" "${UNINST_EXE}"
WriteRegStr HKLM "${INSTDIR_REG_KEY}" "UninstallString" "$INSTDIR\Uninst-pcsx2.exe"
WriteRegDWORD HKLM "${INSTDIR_REG_KEY}" "NoModify" 1
WriteRegDWORD HKLM "${INSTDIR_REG_KEY}" "NoRepair" 1
WriteUninstaller "${UNINST_EXE}"
RMDir /r "$TEMP\PCSX2_installer_temp"
WriteUninstaller "$INSTDIR\Uninst-pcsx2.exe"
SectionEnd
Section "" SID_PCSX2

View File

@ -8,12 +8,7 @@ RequestExecutionLevel user
!define OUTFILE_POSTFIX "setup"
OutFile "pcsx2-${APP_VERSION}-${OUTFILE_POSTFIX}.exe"
Var UserPrivileges
Var IsAdmin
Var DirectXSetupError
; Dialogs and Controls
Var hwnd
Var PreInstall_Dialog
Var PreInstall_DlgBack
Var PreInstall_DlgNext
@ -35,37 +30,10 @@ Page Custom IsUserAdmin
Page Custom PreInstallDialog
Page Custom InstallMode InstallModeLeave
Function IsUserAdmin
!include WinVer.nsh
# No user should ever have to experience this pain ;)
${IfNot} ${AtLeastWinVista}
MessageBox MB_OK "Your operating system is unsupported by PCSX2. Please upgrade your operating system or install PCSX2 1.4.0."
Quit
${EndIf}
ClearErrors
UserInfo::GetName
Pop $R8
UserInfo::GetOriginalAccountType
Pop $UserPrivileges
# GetOriginalAccountType will check the tokens of the original user of the
# current thread/process. If the user tokens were elevated or limited for
# this process, GetOriginalAccountType will return the non-restricted
# account type.
# On Vista with UAC, for example, this is not the same value when running
# with `RequestExecutionLevel user`. GetOriginalAccountType will return
# "admin" while GetAccountType will return "user".
;UserInfo::GetOriginalAccountType
;Pop $R2
${If} $UserPrivileges == "Admin"
StrCpy $IsAdmin 1
${ElseIf} $UserPrivileges == "User"
StrCpy $IsAdmin 0
${EndIf}
FunctionEnd
; Function located in SharedDefs
Section ""
Call IsUserAdmin
SectionEnd
Function PreInstallDialog
@ -85,73 +53,23 @@ FunctionEnd
Function NSD_Timer.Callback
${NSD_KillTimer} NSD_Timer.Callback
SendMessage $hwnd ${PBM_SETRANGE32} 0 100
!include WinVer.nsh
!include "X64.nsh"
# If the user is running at least Windows 8.1
# or has no admin rights, don't waste time trying
# to install the DX and VS runtimes.
${If} ${AtLeastWin8.1}
${OrIf} $IsAdmin == 0
Goto CopyInstallerFiles
SendMessage $HWNDPARENT ${WM_COMMAND} 1 0
${EndIf}
# Check if the VC runtimes are installed
${If} ${RunningX64}
ReadRegDword $R0 HKLM "SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Installed"
${Else}
ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Installed"
${EndIf}
Pop $R0
# If the runtimes are already here, check for DX.
${If} $R0 == "1"
Goto ExecDxSetup
${EndIf}
# Download and install the VC redistributable from the internet
${NSD_CreateLabel} 0 45 100% 10u "Downloading Visual C++ package"
Pop $hwnd
inetc::get "https://aka.ms/vs/16/release/VC_redist.x86.exe" "$TEMP\vcredist_Update_x86.exe" /SILENT /CONNECTTIMEOUT 30 /RECEIVETIMEOUT 30 /END
${NSD_CreateLabel} 0 45 100% 10u "Installing Visual C++ package"
Pop $hwnd
ExecWait '"$TEMP\vcredist_Update_x86.exe /S"'
SendMessage $hwnd ${PBM_SETPOS} 40 0
Delete "$TEMP\vcredist_Update_x86.exe"
# Download and install DirectX
ExecDxSetup:
${NSD_CreateLabel} 0 45 100% 10u "Installing DXWebSetup package"
Pop $hwnd
SendMessage $hwnd ${PBM_SETPOS} 80 0
SetOutPath "$TEMP"
File "dxwebsetup.exe"
ExecWait '"$TEMP\dxwebsetup.exe" /Q' $DirectXSetupError
SendMessage $hwnd ${PBM_SETPOS} 100 0
Delete "$TEMP\dxwebsetup.exe"
Sleep 20
;-----------------------------------------
; Copy installer files to a temp directory instead of repacking twice (for each installer)
CopyInstallerFiles:
${NSD_CreateLabel} 0 45 80% 10u "Unpacking files. Maybe it's time to upgrade that computer!"
SetOutPath "$TEMP\PCSX2_installer_temp"
SetOutPath "$TEMP\PCSX2 ${APP_VERSION}"
File ..\bin\pcsx2.exe
File ..\bin\GameIndex.dbf
File ..\bin\cheats_ws.zip
File ..\bin\PCSX2_keys.ini.default
SetOutPath "$TEMP\PCSX2_installer_temp\Docs"
SetOutPath "$TEMP\PCSX2 ${APP_VERSION}\Docs"
File ..\bin\docs\*
SetOutPath "$TEMP\PCSX2_installer_temp\Shaders"
SetOutPath "$TEMP\PCSX2 ${APP_VERSION}\Shaders"
File ..\bin\shaders\GSdx.fx
File ..\bin\shaders\GSdx_FX_Settings.ini
SetOutPath "$TEMP\PCSX2_installer_temp\Plugins"
SetOutPath "$TEMP\PCSX2 ${APP_VERSION}\Plugins"
File /nonfatal ..\bin\Plugins\gsdx32-sse2.dll
File /nonfatal ..\bin\Plugins\gsdx32-sse4.dll
File /nonfatal ..\bin\Plugins\gsdx32-avx2.dll
@ -162,7 +80,7 @@ CopyInstallerFiles:
File /nonfatal ..\bin\Plugins\DEV9null.dll
File /nonfatal ..\bin\Plugins\FWnull.dll
SetOutPath "$TEMP\PCSX2_installer_temp\Langs"
SetOutPath "$TEMP\PCSX2 ${APP_VERSION}\Langs"
File /nonfatal /r ..\bin\Langs\*.mo
${NSD_CreateLabel} 0 45 100% 10u "Moving on"
;-----------------------------------------
@ -258,7 +176,7 @@ FunctionEnd
!include "ApplyExeProps.nsh"
; The default installation directory for the portable binary.
InstallDir "$DOCUMENTS\$R8\PCSX2 ${APP_VERSION}"
InstallDir "$DOCUMENTS\PCSX2 ${APP_VERSION}"
; Path references for the core files here
!include "SharedCore.nsh"
@ -266,7 +184,7 @@ InstallDir "$DOCUMENTS\$R8\PCSX2 ${APP_VERSION}"
Section "" INST_PORTABLE
SetOutPath "$INSTDIR"
File portable.ini
RMDir /r "$TEMP\PCSX2_installer_temp"
RMDir /r "$TEMP\PCSX2 ${APP_VERSION}"
SectionEnd
Section "" SID_PCSX2