; ============================================================================ ; PolyMech media-img — NSIS installer ; ============================================================================ ; From packages/media/cpp: ; npm run build:installer ; Output: dist\media-img-Setup.exe ; Requires: NSIS 3+, CMake release build (dist\pm-image.exe + vips DLLs) ; ============================================================================ !include "MUI2.nsh" !include "FileFunc.nsh" !include "WinMessages.nsh" ; --------------------------------------------------------------------------- ; Self-contained string helpers (PATH edit) ; --------------------------------------------------------------------------- !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}` Call StrContains Pop `${ResultVar}` !macroend !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 Image Resizer" !define PRODUCT_VERSION "0.1.0" !define PRODUCT_PUBLISHER "PolyMech" !define PRODUCT_WEB_SITE "https://service.polymech.info/user/cgo/pages/polymech-media-tools" !define PRODUCT_EXE "pm-image.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define ENV_KEY "Environment" Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "dist\pm-images-setup.exe" InstallDir "" RequestExecutionLevel user Var IsAdmin !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" 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 Section "Install" SetOutPath "$INSTDIR" File "dist\${PRODUCT_EXE}" File /nonfatal "dist\*.dll" ; libvips optional modules (HEIF, etc.) — copied next to media-img by CMake SetOutPath "$INSTDIR\vips-modules-8.18" File /r "dist\vips-modules-8.18\*.*" SetOutPath "$INSTDIR\scripts" File "..\scripts\explorer-resize.ps1" File "..\scripts\explorer-convert.ps1" File "..\scripts\explorer-ui.ps1" SetOutPath "$INSTDIR" WriteUninstaller "$INSTDIR\Uninstall.exe" CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_EXE}" "--help" CreateShortcut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe" 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 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: ;Call AddToPath DetailPrint "Registering Explorer context menu (media-img register-explorer)..." ExecWait '"$INSTDIR\${PRODUCT_EXE}" register-explorer' $0 SectionEnd Section "Uninstall" DetailPrint "Removing Explorer context menu..." IfFileExists "$INSTDIR\${PRODUCT_EXE}" 0 skip_unreg_explorer ExecWait '"$INSTDIR\${PRODUCT_EXE}" register-explorer --unregister --no-refresh-shell' $0 skip_unreg_explorer: Delete "$INSTDIR\${PRODUCT_EXE}" Delete "$INSTDIR\*.dll" RMDir /r "$INSTDIR\vips-modules-8.18" Delete "$INSTDIR\scripts\explorer-resize.ps1" Delete "$INSTDIR\scripts\explorer-convert.ps1" Delete "$INSTDIR\scripts\explorer-ui.ps1" RMDir "$INSTDIR\scripts" Delete "$INSTDIR\Uninstall.exe" RMDir "$INSTDIR" Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" RMDir "$SMPROGRAMS\${PRODUCT_NAME}" 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: Call un.RemoveFromPath SectionEnd 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" !insertmacro StrReplace $1 "$0" ";$INSTDIR" "" StrCmp $1 "$0" 0 write_path !insertmacro StrReplace $1 "$0" "$INSTDIR;" "" StrCmp $1 "$0" 0 write_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