mono/packages/cad/scripts/installer.nsi
2026-03-14 19:03:09 +01:00

302 lines
9.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; ============================================================================
; PolyMech CAD Tools - NSIS Installer
; ============================================================================
; Build: makensis scripts\installer.nsi (run from packages/cad)
; Output: dist\PolyMechCAD-Setup.exe
; ============================================================================
!include "MUI2.nsh"
!include "FileFunc.nsh"
!include "WinMessages.nsh"
; ---------------------------------------------------------------------------
; Self-contained string helpers (replace StrFunc.nsh for portability)
; ---------------------------------------------------------------------------
; -- StrContains: check if SubString exists in String --
!macro _StrContainsConstructor un
Function ${un}StrContains
Exch $R1 ; SubString
Exch 1
Exch $R0 ; String
Push $R2
Push $R3
Push $R4
StrLen $R2 $R0
StrLen $R3 $R1
StrCpy $R4 0
loop:
IntCmp $R4 $R2 notfound 0 notfound
StrCpy $R5 $R0 $R3 $R4
StrCmp $R5 $R1 found
IntOp $R4 $R4 + 1
Goto loop
found:
StrCpy $R0 $R1
Goto done
notfound:
StrCpy $R0 ""
done:
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
!macroend
!insertmacro _StrContainsConstructor ""
!macro StrContains ResultVar String SubString
Push `${String}`
Push `${SubString}`
!ifdef __UNINSTALL__
Call un.StrContains
!else
Call StrContains
!endif
Pop `${ResultVar}`
!macroend
; -- StrReplace: replace all occurrences of Old with New in String --
!macro _StrReplaceConstructor un
Function ${un}StrReplace
Exch $R2 ; New
Exch 1
Exch $R1 ; Old
Exch 2
Exch $R0 ; String
Push $R3
Push $R4
Push $R5
Push $R6
Push $R7
Push $R8
Push $R9
StrCpy $R3 0
StrLen $R4 $R1
StrLen $R6 $R0
StrLen $R9 $R2
loop:
StrCpy $R5 $R0 $R4 $R3
StrCmp $R5 $R1 found
StrCmp $R3 $R6 done
IntOp $R3 $R3 + 1
Goto loop
found:
StrCpy $R5 $R0 $R3
IntOp $R8 $R3 + $R4
StrCpy $R7 $R0 "" $R8
StrCpy $R0 "$R5$R2$R7"
StrLen $R6 $R0
IntOp $R3 $R3 + $R9
Goto loop
done:
Pop $R9
Pop $R8
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Push $R0
Exch 3
Pop $R1
Pop $R0
Pop $R2
FunctionEnd
!macroend
!insertmacro _StrReplaceConstructor ""
!insertmacro _StrReplaceConstructor "un."
!macro StrReplace ResultVar String Old New
Push `${String}`
Push `${Old}`
Push `${New}`
!ifdef __UNINSTALL__
Call un.StrReplace
!else
Call StrReplace
!endif
Pop `${ResultVar}`
!macroend
; ---------------------------------------------------------------------------
; Metadata
; ---------------------------------------------------------------------------
!define PRODUCT_NAME "PolyMech CAD Tools"
!define PRODUCT_VERSION "1.8.9"
!define PRODUCT_PUBLISHER "PlasticHub"
!define PRODUCT_WEB_SITE "https://git.polymech.info/mono/cad"
!define PRODUCT_EXE "pm-cad.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define ENV_KEY "Environment"
; ---------------------------------------------------------------------------
; General set base directory to packages/cad (parent of scripts/)
; ---------------------------------------------------------------------------
!cd ".."
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "dist\PolyMechCAD-Setup.exe"
InstallDir "" ; set dynamically in .onInit
RequestExecutionLevel user ; no UAC; right-click "Run as admin" for all-users
; Runtime variable: "1" = all users (admin), "0" = current user
Var IsAdmin
; ---------------------------------------------------------------------------
; Modern UI pages
; ---------------------------------------------------------------------------
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
!define MUI_ABORTWARNING
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
; ---------------------------------------------------------------------------
; .onInit detect admin rights, set default install dir
; ---------------------------------------------------------------------------
Function .onInit
UserInfo::GetAccountType
Pop $0
StrCmp $0 "Admin" 0 not_admin
StrCpy $IsAdmin "1"
StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCT_NAME}"
Goto init_done
not_admin:
StrCpy $IsAdmin "0"
StrCpy $INSTDIR "$LOCALAPPDATA\${PRODUCT_NAME}"
init_done:
FunctionEnd
; ---------------------------------------------------------------------------
; Install section
; ---------------------------------------------------------------------------
Section "Install"
SetOutPath "$INSTDIR"
; -- Main executable (from nexe build) --
File "dist\win-64\${PRODUCT_EXE}"
; -- sw directory (runtime dependencies) --
; Exclude .NET build artifacts and source tool dirs
SetOutPath "$INSTDIR\sw"
File /r /x *.pdb /x *.deps.json /x *.runtimeconfig.dev.json /x tools "sw\*.*"
; -- Uninstaller --
SetOutPath "$INSTDIR"
WriteUninstaller "$INSTDIR\Uninstall.exe"
; -- Start Menu shortcuts --
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_EXE}" "--help"
CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
; -- Add/Remove Programs registry (HKLM for admin, HKCU for user) --
StrCmp $IsAdmin "1" 0 reg_user
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "NoModify" 1
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "NoRepair" 1
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "EstimatedSize" $0
; Store install mode so uninstaller knows which hive to clean
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallMode" "AllUsers"
Goto reg_done
reg_user:
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}"
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}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "NoModify" 1
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "NoRepair" 1
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "EstimatedSize" $0
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "InstallMode" "CurrentUser"
reg_done:
; -- Add to user PATH (always HKCU) --
Call AddToPath
SectionEnd
; ---------------------------------------------------------------------------
; Uninstall section
; ---------------------------------------------------------------------------
Section "Uninstall"
; -- Remove files --
RMDir /r "$INSTDIR\sw"
Delete "$INSTDIR\${PRODUCT_EXE}"
Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR"
; -- Start Menu --
Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk"
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
; -- Registry: check which hive was used during install --
ReadRegStr $0 HKLM "${PRODUCT_UNINST_KEY}" "InstallMode"
StrCmp $0 "AllUsers" 0 unreg_user
DeleteRegKey HKLM "${PRODUCT_UNINST_KEY}"
Goto unreg_done
unreg_user:
DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}"
unreg_done:
; -- Remove from user PATH --
Call un.RemoveFromPath
SectionEnd
; ---------------------------------------------------------------------------
; PATH helper functions (always user-space HKCU)
; ---------------------------------------------------------------------------
Function AddToPath
ReadRegStr $0 HKCU "${ENV_KEY}" "Path"
!insertmacro StrContains $1 "$0" "$INSTDIR"
StrCmp $1 "" 0 already_in_path
StrCpy $0 "$0;$INSTDIR"
WriteRegExpandStr HKCU "${ENV_KEY}" "Path" "$0"
SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=5000
already_in_path:
FunctionEnd
Function un.RemoveFromPath
ReadRegStr $0 HKCU "${ENV_KEY}" "Path"
; Try ";$INSTDIR" first (middle or end of PATH)
!insertmacro StrReplace $1 "$0" ";$INSTDIR" ""
StrCmp $1 "$0" 0 write_path
; Try "$INSTDIR;" (beginning of PATH)
!insertmacro StrReplace $1 "$0" "$INSTDIR;" ""
StrCmp $1 "$0" 0 write_path
; Try exact match (only entry in PATH)
!insertmacro StrReplace $1 "$0" "$INSTDIR" ""
StrCmp $1 "$0" done_path
write_path:
WriteRegExpandStr HKCU "${ENV_KEY}" "Path" "$1"
SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=5000
done_path:
FunctionEnd