302 lines
9.1 KiB
Plaintext
302 lines
9.1 KiB
Plaintext
; ============================================================================
|
||
; 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
|