; 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