Files
dashcaddy/installer/windows/dashcaddy.nsi
T
Hermes 86e4c9fc81 wip: Windows desktop app scaffold (WinUI 3/.NET 8) + NSIS installer + docs
Owner decision pending (STATE.md DC-100 tick): adopt/ship/park.
Preserved from fragile git stash to named branch 2026-08-23.
NOTE: requires a Windows build machine (WinUI XAML compiler + MSIX do not
cross-build on Linux) — see WINDOWS_APP_BUILD.md in this tree.
Secret-scanned clean 2026-08-23 (no keys/tokens/PEM in tree).
2026-08-22 23:50:34 -07:00

220 lines
8.8 KiB
NSIS

; DashCaddy Windows Installer (NSIS)
; Build: makensis /DVERSION=1.15.0 installer/windows/dashcaddy.nsi
; Output: DashCaddy-Setup-1.15.0.exe
;
; This installer:
; 1. Installs DashCaddy Desktop app (WinUI 3, MSIX-packaged)
; 2. Installs Docker Desktop via winget (if not present)
; 3. Enables WSL2 (if needed, with reboot handling)
; 4. Pulls Docker images
; 5. Starts services
; 6. Creates Start Menu shortcuts
; 7. Registers for auto-updates via MSIX
!include "MUI2.nsh"
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!include "x64.nsh"
!include "WinShell.nsh"
!include "nsProcess.nsh"
; ─────────────────────────────────────────────────────────────────
; Product Information
; ─────────────────────────────────────────────────────────────────
!define PRODUCT_NAME "DashCaddy"
!define PRODUCT_VERSION "1.15.0"
!define PRODUCT_PUBLISHER "Sami Ahmed"
!define PRODUCT_WEB_SITE "https://dashcaddy.net"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKCU" ; Per-user install (no admin required)
; ─────────────────────────────────────────────────────────────────
; Installer Configuration
; ─────────────────────────────────────────────────────────────────
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "DashCaddy-Setup-${PRODUCT_VERSION}.exe"
InstallDir "$LOCALAPPDATA\DashCaddy"
RequestExecutionLevel user
ShowInstDetails show
XPStyle on
; ─────────────────────────────────────────────────────────────────
; Modern UI
; ─────────────────────────────────────────────────────────────────
!define MUI_ABORTWARNING
!define MUI_ICON "assets\dashcaddy.ico"
!define MUI_UNICON "assets\dashcaddy.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "assets\welcome.bmp"
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "assets\LICENSE.txt"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN "$INSTDIR\DashCaddy.exe"
!define MUI_FINISHPAGE_RUN_TEXT "Launch DashCaddy"
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
; ─────────────────────────────────────────────────────────────────
; Variables
; ─────────────────────────────────────────────────────────────────
Var /GLOBAL DockerInstalled
Var /GLOBAL WSLEnabled
Var /GLOBAL RebootRequired
; ─────────────────────────────────────────────────────────────────
; Sections
; ─────────────────────────────────────────────────────────────────
Section "DashCaddy Application (Required)" SecApp
SectionIn RO
SetOutPath "$INSTDIR"
File /r "app\*"
File "DashCaddy.exe"
File "config.yaml.example"
File "README.md"
File "LICENSE"
; Write uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
; Register in Add/Remove Programs (HKCU)
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME} ${PRODUCT_VERSION}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\assets\dashcaddy.ico"
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "NoModify" 1
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "NoRepair" 1
; Start Menu
CreateDirectory "$SMPROGRAMS\DashCaddy"
CreateShortCut "$SMPROGRAMS\DashCaddy\DashCaddy.lnk" "$INSTDIR\DashCaddy.exe" "" "$INSTDIR\assets\dashcaddy.ico" 0
CreateShortCut "$SMPROGRAMS\DashCaddy\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\assets\dashcaddy.ico" 0
SectionEnd
Section "Docker Desktop (Auto-Install)" SecDocker
SectionIn 1
; Docker Desktop installed via bootstrap.ps1
SectionEnd
Section "WSL 2 Support (Required for Docker)" SecWSL
SectionIn 1
; WSL2 enabled via bootstrap.ps1
SectionEnd
Section "Desktop Shortcut" SecShortcut
SectionIn 1
CreateShortCut "$DESKTOP\DashCaddy.lnk" "$INSTDIR\DashCaddy.exe" "" "$INSTDIR\assets\dashcaddy.ico" 0
SectionEnd
Section "Auto-Start on Login" SecAutostart
SectionIn 1
; Registered via bootstrap.ps1
SectionEnd
; ─────────────────────────────────────────────────────────────────
; Installer Functions
; ─────────────────────────────────────────────────────────────────
Function .onInit
; Check Windows 10/11
${If} ${AtLeastWin10} == 0
MessageBox MB_ICONSTOP "DashCaddy requires Windows 10 (build 19041) or later.$\n$\nCurrent OS: Windows $0"
Abort
${EndIf}
; Check if already running
FindWindow $0 "DashCaddyWindowClass"
${If} $0 <> 0
MessageBox MB_YESNO|MB_ICONQUESTION "DashCaddy is currently running. Close it before installing?$\n$\n(Recommended: Yes)" IDYES CloseRunning
Abort
CloseRunning:
SendMessage $0 ${WM_CLOSE} 0 0
Sleep 1000
${EndIf}
; Pre-check Docker
nsExec::ExecToLog 'where docker.exe'
Pop $0
${If} $0 == 0
StrCpy $DockerInstalled 1
${Else}
StrCpy $DockerInstalled 0
${EndIf}
; Pre-check WSL2
nsExec::ExecToLog 'wsl --status'
Pop $0
${If} $0 == 0
StrCpy $WSLEnabled 1
${Else}
StrCpy $WSLEnabled 0
${EndIf}
FunctionEnd
Function .onInstSuccess
; Run bootstrap (installs Docker, enables WSL, pulls images, starts services)
ExecWait '"$INSTDIR\bootstrap.ps1"'
; Launch app
Exec '"$INSTDIR\DashCaddy.exe"'
FunctionEnd
; ─────────────────────────────────────────────────────────────────
; Uninstaller
; ─────────────────────────────────────────────────────────────────
Section Uninstall
; Stop app if running
FindWindow $0 "DashCaddyWindowClass"
${If} $0 <> 0
SendMessage $0 ${WM_CLOSE} 0 0
Sleep 1000
${EndIf}
; Stop Docker containers
ExecWait '"$INSTDIR\bootstrap.ps1" -Action Stop'
; Remove auto-start
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "DashCaddy"
; Remove Start Menu shortcuts
Delete "$SMPROGRAMS\DashCaddy\*.*"
RMDir "$SMPROGRAMS\DashCaddy"
; Remove Desktop shortcut
Delete "$DESKTOP\DashCaddy.lnk"
; Remove installed files
Delete "$INSTDIR\*.exe"
Delete "$INSTDIR\*.yaml"
Delete "$INSTDIR\*.md"
Delete "$INSTDIR\*.txt"
Delete "$INSTDIR\*.ico"
RMDir /r "$INSTDIR\app"
RMDir /r "$INSTDIR\assets"
; Remove uninstaller
Delete "$INSTDIR\Uninstall.exe"
; Remove registry keys
DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}"
; Remove directory if empty
RMDir "$INSTDIR"
; Note: Docker Desktop and WSL2 are LEFT installed (shared system components)
; User data in %LOCALAPPDATA%\DashCaddy\data is preserved
SectionEnd
Function un.onUninstSuccess
HideWindow
MessageBox MB_OK "DashCaddy has been uninstalled.$\n$\nYour data in %LOCALAPPDATA%\DashCaddy\data was preserved.$\n$\nDocker Desktop and WSL2 were left installed.$\n$\nTo completely remove all data, manually delete %LOCALAPPDATA%\DashCaddy\"
FunctionEnd