[Installer] Add an Inno Setup generator next to NSIS.

COCKATRICE_WIN_INSTALLER chooses which tool writes the Windows installer.
NSIS stays the default, so nothing on the existing path changes; InnoSetup
selects CPack's own INNOSETUP generator (CMake >= 3.27) and builds from the
same install() rules. Both can be built from one tree and the resulting
installers compared on an upgrade from 3.1.x.

What the Inno path does differently:

- Installs over the previous version instead of running the old uninstaller
  first, which is what the backup/restore pair in the NSIS template exists
  to survive.
- Closes and restarts a running application through Windows Restart Manager
  (CloseApplications/RestartApplications) instead of the two PowerShell
  process guards the template needed.
- Removes stale runtime with one [InstallDelete] of *.dll and Plugins,
  instead of RetryDllPurge and its diagnostics.
- Writes a log on every run through SetupLogging, instead of CockLog.
- Resolves the install directory from the legacy NSIS registration, and
  deletes that registration after a successful install so the old
  uninstaller (whose blanket directory removal caused the 3.1.x data loss)
  cannot be run after the upgrade.
- Keeps the portable mode the client detects, the C++ runtime bootstrap and
  the /PORTABLE switch.

The in-app updater still passes the NSIS switches (/R, /PID=); the installer
logs them so the first Windows run settles whether Inno Setup accepts them or
the switch-over needs a client version gate.

The installer content check in .ci/compile.sh learns to strip Inno Setup's
{app} prefix from the paths 7-Zip lists, so the required-runtime comparison
works for either archive format.
This commit is contained in:
Lukas Brübach 2026-10-26 07:52:44 +01:00
parent 675e1f7447
commit 2c8e47a0a4
5 changed files with 333 additions and 20 deletions

View file

@ -327,15 +327,32 @@ if(UNIX)
endif()
endif()
elseif(WIN32)
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(TRICE_IS_64_BIT 1)
else()
set(TRICE_IS_64_BIT 0)
# Which tool writes the installer. NSIS is the incumbent and stays the default;
# InnoSetup selects CPack's own Inno Setup generator (see cmake/InnoSetup.cmake). Both
# consume the same install() rules, so this is a packaging choice, never a build change,
# and the two installers can be built from one tree and compared on a real upgrade.
set(COCKATRICE_WIN_INSTALLER
"NSIS"
CACHE STRING "Windows installer generator: NSIS (incumbent) or InnoSetup"
)
set_property(CACHE COCKATRICE_WIN_INSTALLER PROPERTY STRINGS NSIS InnoSetup)
if(NOT COCKATRICE_WIN_INSTALLER MATCHES "^(NSIS|InnoSetup)$")
message(FATAL_ERROR "COCKATRICE_WIN_INSTALLER must be NSIS or InnoSetup, not '${COCKATRICE_WIN_INSTALLER}'")
endif()
# Configure file with custom definitions for NSIS.
configure_file("${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in" "${PROJECT_BINARY_DIR}/NSIS.definitions.nsh")
if(COCKATRICE_WIN_INSTALLER STREQUAL "InnoSetup")
include(${COCKATRICE_CMAKE_PATH}/InnoSetup.cmake)
else()
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(TRICE_IS_64_BIT 1)
else()
set(TRICE_IS_64_BIT 0)
endif()
# Configure file with custom definitions for NSIS.
configure_file("${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in" "${PROJECT_BINARY_DIR}/NSIS.definitions.nsh")
endif()
# Installer-log sender for the AbortInstall Sentry hook (values parsed out of COCKATRICE_SENTRY_DSN in
# cmake/CrashReporting.cmake). Generated only when a DSN was parsed: cmake/NSIS.template.in embeds it under
@ -379,7 +396,9 @@ elseif(WIN32)
# is available to CMake, requiring the vcpkg half would mean guessing names
# again, which is what produced this bug report in the first place. So assert
# what is derived from the build's own link lists and leave the rest to the
# purge in cmake/NSIS.template.in, which removes every DLL regardless of name.
# installer's own delete: the purge in cmake/NSIS.template.in and the
# install-delete section in cmake/InnoSetup.install.iss both remove every DLL
# regardless of name.
set(_required_runtime "")
foreach(_qt_module IN LISTS COCKATRICE_QT_MODULES SERVATRICE_QT_MODULES ORACLE_QT_MODULES)
get_target_property(_qt_module_type ${_qt_module} TYPE)
@ -395,7 +414,7 @@ elseif(WIN32)
string(REPLACE ";" "\n" _required_runtime "${_required_runtime}")
file(WRITE "${PROJECT_BINARY_DIR}/required-runtime.txt" "${_required_runtime}\n")
# include vcredist into the package; NSIS will take care of running it
# include vcredist into the package; both installers run it after the payload
if(VCREDISTRUNTIME_FOUND)
install(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
endif()