hypertwist/packaging/windows/HyperTwistInstaller.nsi
2026-07-26 09:41:16 +00:00

331 lines
11 KiB
NSIS

Unicode true
!include "MUI2.nsh"
!include "LogicLib.nsh"
!include "WinVer.nsh"
!include "x64.nsh"
!include "FileFunc.nsh"
!ifndef PRODUCT_VERSION
!error "PRODUCT_VERSION is required."
!endif
!ifndef DISPLAY_VERSION
!error "DISPLAY_VERSION is required."
!endif
!ifndef RELEASE_ID
!error "RELEASE_ID is required."
!endif
!ifndef OUTPUT_FILE
!error "OUTPUT_FILE is required."
!endif
!ifndef PAYLOAD_ROOT
!error "PAYLOAD_ROOT is required."
!endif
!ifndef PAYLOAD_MANIFEST
!error "PAYLOAD_MANIFEST is required."
!endif
!ifndef READINESS_SCRIPT
!error "READINESS_SCRIPT is required."
!endif
!ifndef VC_REDIST_PATH
!error "VC_REDIST_PATH is required."
!endif
!ifndef INSTALLER_ICON
!error "INSTALLER_ICON is required."
!endif
!ifndef PAYLOAD_SIZE_KB
!error "PAYLOAD_SIZE_KB is required."
!endif
!define PRODUCT_NAME "HyperTwist"
!define PRODUCT_CHANNEL "Alpha"
!define PRODUCT_PUBLISHER "HyperTwist"
!define PRODUCT_WEBSITE "https://hypertwist.app"
!define PRODUCT_SUPPORT "https://hypertwist.app/support"
!define PRODUCT_REG_KEY "Software\HyperTwist\HyperTwist"
!define PRODUCT_UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\HyperTwist"
!define INSTALL_MARKER "HyperTwist.install-marker"
Name "${PRODUCT_NAME} ${PRODUCT_CHANNEL}"
Caption "${PRODUCT_NAME} ${DISPLAY_VERSION} Setup"
BrandingText "${PRODUCT_NAME} | Explore dimensions beyond the ordinary"
OutFile "${OUTPUT_FILE}"
InstallDir "$PROGRAMFILES64\HyperTwist"
RequestExecutionLevel admin
CRCCheck force
SetDatablockOptimize on
SetCompressor /SOLID lzma
SetCompressorDictSize 64
ShowInstDetails show
ShowUninstDetails show
ManifestDPIAware true
ManifestSupportedOS all
Icon "${INSTALLER_ICON}"
UninstallIcon "${INSTALLER_ICON}"
VIProductVersion "${PRODUCT_VERSION}"
VIAddVersionKey /LANG=1033 "ProductName" "${PRODUCT_NAME}"
VIAddVersionKey /LANG=1033 "ProductVersion" "${DISPLAY_VERSION}"
VIAddVersionKey /LANG=1033 "CompanyName" "${PRODUCT_PUBLISHER}"
VIAddVersionKey /LANG=1033 "FileDescription" "${PRODUCT_NAME} ${PRODUCT_CHANNEL} Installer"
VIAddVersionKey /LANG=1033 "FileVersion" "${PRODUCT_VERSION}"
VIAddVersionKey /LANG=1033 "LegalCopyright" "Copyright (c) HyperTwist"
VIAddVersionKey /LANG=1033 "OriginalFilename" "HyperTwist-Setup.exe"
!define MUI_ABORTWARNING
!define MUI_ICON "${INSTALLER_ICON}"
!define MUI_UNICON "${INSTALLER_ICON}"
!define MUI_FINISHPAGE_LINK "Visit hypertwist.app"
!define MUI_FINISHPAGE_LINK_LOCATION "${PRODUCT_WEBSITE}"
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
Function .onInit
SetRegView 64
${IfNot} ${RunningX64}
MessageBox MB_OK|MB_ICONSTOP \
"HyperTwist requires 64-bit Windows." \
/SD IDOK
SetErrorLevel 10
Quit
${EndIf}
${IfNot} ${AtLeastWin10}
MessageBox MB_OK|MB_ICONSTOP \
"HyperTwist requires Windows 10 version 22H2 or Windows 11." \
/SD IDOK
SetErrorLevel 11
Quit
${EndIf}
ReadRegStr $1 HKLM "${PRODUCT_REG_KEY}" "InstallLocation"
StrCmp $1 "" install_location_ready
StrCpy $INSTDIR $1
install_location_ready:
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentBuildNumber"
IntCmp $0 19045 windows_build_ok windows_build_too_old windows_build_ok
windows_build_too_old:
MessageBox MB_OK|MB_ICONSTOP \
"This Windows build is too old for the supported HyperTwist Alpha baseline. Update to Windows 10 22H2 or Windows 11 and try again." \
/SD IDOK
SetErrorLevel 12
Quit
windows_build_ok:
FunctionEnd
Function CleanOwnedPayloadForUpgrade
ReadRegStr $0 HKLM "${PRODUCT_REG_KEY}" "InstallLocation"
StrCmp $0 $INSTDIR registry_owner_confirmed cleanup_done
registry_owner_confirmed:
IfFileExists "$INSTDIR\Installer\${INSTALL_MARKER}" 0 cleanup_done
DetailPrint "Removing the previous HyperTwist payload before upgrade."
RMDir /r "$INSTDIR\Content"
RMDir /r "$INSTDIR\Engine"
RMDir /r "$INSTDIR\UnrealHyperTwist"
RMDir /r "$INSTDIR\Installer"
Delete "$INSTDIR\Manifest_DebugFiles_Win64.txt"
Delete "$INSTDIR\Manifest_NonUFSFiles_Win64.txt"
Delete "$INSTDIR\Manifest_UFSFiles_Win64.txt"
Delete "$INSTDIR\UnrealHyperTwist.exe"
Delete "$INSTDIR\Uninstall HyperTwist.exe"
cleanup_done:
FunctionEnd
Function AssertSafeInstallLocation
${GetFileName} "$INSTDIR" $0
StrCmp $0 "HyperTwist" install_leaf_safe install_location_refused
install_leaf_safe:
ReadRegStr $0 HKLM "${PRODUCT_REG_KEY}" "InstallLocation"
StrCmp $0 $INSTDIR install_registry_owner_candidate install_unowned_scan
install_registry_owner_candidate:
IfFileExists "$INSTDIR\Installer\${INSTALL_MARKER}" install_location_safe install_unowned_scan
install_unowned_scan:
FindFirst $0 $1 "$INSTDIR\*"
install_unowned_scan_next:
StrCmp $1 "" install_unowned_empty
StrCmp $1 "." install_unowned_continue
StrCmp $1 ".." install_unowned_continue
FindClose $0
MessageBox MB_OK|MB_ICONSTOP \
"The selected HyperTwist folder is not empty and is not owned by an existing registered HyperTwist installation. Choose an empty folder named HyperTwist." \
/SD IDOK
SetErrorLevel 14
Abort
install_unowned_continue:
FindNext $0 $1
Goto install_unowned_scan_next
install_unowned_empty:
FindClose $0
Goto install_location_safe
install_location_refused:
MessageBox MB_OK|MB_ICONSTOP \
"The installation folder itself must be named HyperTwist, for example C:\Program Files\HyperTwist or D:\Games\HyperTwist." \
/SD IDOK
SetErrorLevel 13
Abort
install_location_safe:
FunctionEnd
Section -ValidateInstallLocation
Call AssertSafeInstallLocation
SectionEnd
Section -MicrosoftRuntime
SetOutPath "$PLUGINSDIR"
File /oname=vc_redist.x64.exe "${VC_REDIST_PATH}"
DetailPrint "Installing or repairing the Microsoft Visual C++ 2015-2022 x64 runtime."
ExecWait '"$PLUGINSDIR\vc_redist.x64.exe" /install /quiet /norestart' $0
${If} $0 == 3010
DetailPrint "The Microsoft runtime requested a restart."
SetRebootFlag true
${ElseIf} $0 == 1638
DetailPrint "A compatible or newer Microsoft runtime is already installed."
${ElseIf} $0 != 0
MessageBox MB_OK|MB_ICONSTOP \
"Microsoft Visual C++ runtime setup failed with exit code $0. HyperTwist was not installed." \
/SD IDOK
SetErrorLevel 20
Abort
${EndIf}
SectionEnd
Section "!HyperTwist application" SEC_CORE
SectionIn RO
AddSize ${PAYLOAD_SIZE_KB}
; Do not disturb a working prior install until every bundled prerequisite succeeds.
Call CleanOwnedPayloadForUpgrade
SetOutPath "$INSTDIR"
File /r \
/x "*.pdb" \
/x "Manifest_DebugFiles_Win64.txt" \
"${PAYLOAD_ROOT}\*"
SetOutPath "$INSTDIR\Installer"
File /oname=payload-manifest.json "${PAYLOAD_MANIFEST}"
File /oname=Test-HyperTwistWindowsReadiness.ps1 "${READINESS_SCRIPT}"
FileOpen $0 "$INSTDIR\Installer\${INSTALL_MARKER}" w
FileWrite $0 "product=HyperTwist$\r$\n"
FileWrite $0 "release=${RELEASE_ID}$\r$\n"
FileWrite $0 "version=${DISPLAY_VERSION}$\r$\n"
FileClose $0
WriteUninstaller "$INSTDIR\Uninstall HyperTwist.exe"
WriteRegStr HKLM "${PRODUCT_REG_KEY}" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "${PRODUCT_REG_KEY}" "ReleaseId" "${RELEASE_ID}"
WriteRegStr HKLM "${PRODUCT_REG_KEY}" "DisplayVersion" "${DISPLAY_VERSION}"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "DisplayName" "${PRODUCT_NAME} ${PRODUCT_CHANNEL}"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "DisplayVersion" "${DISPLAY_VERSION}"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "DisplayIcon" "$INSTDIR\UnrealHyperTwist.exe,0"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "URLInfoAbout" "${PRODUCT_WEBSITE}"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "HelpLink" "${PRODUCT_SUPPORT}"
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "UninstallString" "$\"$INSTDIR\Uninstall HyperTwist.exe$\""
WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "QuietUninstallString" "$\"$INSTDIR\Uninstall HyperTwist.exe$\" /S"
WriteRegDWORD HKLM "${PRODUCT_UNINSTALL_KEY}" "EstimatedSize" ${PAYLOAD_SIZE_KB}
WriteRegDWORD HKLM "${PRODUCT_UNINSTALL_KEY}" "NoModify" 1
WriteRegDWORD HKLM "${PRODUCT_UNINSTALL_KEY}" "NoRepair" 1
SetShellVarContext all
CreateDirectory "$SMPROGRAMS\HyperTwist"
CreateShortCut "$SMPROGRAMS\HyperTwist\HyperTwist.lnk" \
"$INSTDIR\UnrealHyperTwist.exe" "" "$INSTDIR\UnrealHyperTwist.exe" 0
CreateShortCut "$SMPROGRAMS\HyperTwist\System Readiness Report.lnk" \
"$SYSDIR\WindowsPowerShell\v1.0\powershell.exe" \
"-NoProfile -ExecutionPolicy Bypass -File $\"$INSTDIR\Installer\Test-HyperTwistWindowsReadiness.ps1$\" -PayloadRoot $\"$INSTDIR$\" -TargetInstallRoot $\"$INSTDIR$\" -ExpectedPayloadManifestPath $\"$INSTDIR\Installer\payload-manifest.json$\" -WaitForUser" \
"$INSTDIR\UnrealHyperTwist.exe" 0
CreateShortCut "$SMPROGRAMS\HyperTwist\Uninstall HyperTwist.lnk" \
"$INSTDIR\Uninstall HyperTwist.exe"
SectionEnd
Section "Desktop shortcut" SEC_DESKTOP
SetShellVarContext all
CreateShortCut "$DESKTOP\HyperTwist.lnk" \
"$INSTDIR\UnrealHyperTwist.exe" "" "$INSTDIR\UnrealHyperTwist.exe" 0
SectionEnd
LangString DESC_SEC_CORE ${LANG_ENGLISH} \
"The complete HyperTwist desktop Alpha, puzzle runtimes, learning studio, browser shell, and local solver data."
LangString DESC_SEC_DESKTOP ${LANG_ENGLISH} \
"Create an all-users HyperTwist shortcut on the desktop."
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_CORE} $(DESC_SEC_CORE)
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} $(DESC_SEC_DESKTOP)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Section "Uninstall"
SetRegView 64
${GetFileName} "$INSTDIR" $1
StrCmp $1 "HyperTwist" uninstall_leaf_safe uninstall_refused
uninstall_leaf_safe:
ReadRegStr $0 HKLM "${PRODUCT_REG_KEY}" "InstallLocation"
StrCmp $0 $INSTDIR uninstall_registry_owned uninstall_refused
uninstall_registry_owned:
IfFileExists "$INSTDIR\Installer\${INSTALL_MARKER}" uninstall_owned uninstall_refused
uninstall_refused:
MessageBox MB_OK|MB_ICONSTOP \
"HyperTwist registry ownership or the install marker is missing. The uninstaller will not delete an unverified directory." \
/SD IDOK
SetErrorLevel 30
Abort
uninstall_owned:
SetShellVarContext all
Delete "$DESKTOP\HyperTwist.lnk"
RMDir /r "$SMPROGRAMS\HyperTwist"
DeleteRegKey HKLM "${PRODUCT_UNINSTALL_KEY}"
DeleteRegKey HKLM "${PRODUCT_REG_KEY}"
DeleteRegKey /ifempty HKLM "Software\HyperTwist"
RMDir /r "$INSTDIR\Content"
RMDir /r "$INSTDIR\Engine"
RMDir /r "$INSTDIR\UnrealHyperTwist"
Delete "$INSTDIR\Manifest_DebugFiles_Win64.txt"
Delete "$INSTDIR\Manifest_NonUFSFiles_Win64.txt"
Delete "$INSTDIR\Manifest_UFSFiles_Win64.txt"
Delete "$INSTDIR\UnrealHyperTwist.exe"
Delete "$INSTDIR\Installer\payload-manifest.json"
Delete "$INSTDIR\Installer\Test-HyperTwistWindowsReadiness.ps1"
Delete "$INSTDIR\Installer\${INSTALL_MARKER}"
RMDir "$INSTDIR\Installer"
Delete "$INSTDIR\Uninstall HyperTwist.exe"
RMDir "$INSTDIR"
SectionEnd