WindowsInstaller: multiple improvements and fixes
move windowsinstaller to /package update artwork adapt to conda builds make msvc redist directory optional automate version information definition use relative directories for file locations definitions improve/update readme partially update Delete.bat for qt6 libpack add .gitignore update signing.bat and add hashing command WindowsInstaller: use --safe-mode in freecadcmd commands [skip ci] WindowsInstaller: make windows 8 the minimum version [skip ci] WindowsInstaller: allow configuring some values via command line windows installer update for qt6 build
This commit is contained in:
committed by
Adrian Insaurralde Avalos
parent
a847a794c4
commit
d466ba037b
82
package/WindowsInstaller/include/declarations.nsh
Normal file
82
package/WindowsInstaller/include/declarations.nsh
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
declaration.nsh
|
||||
|
||||
Configuration and variables of FreeCAD installer
|
||||
*/
|
||||
|
||||
#--------------------------------
|
||||
# File locations
|
||||
|
||||
!define FILES_LICENSE "license.rtf"
|
||||
|
||||
#--------------------------------
|
||||
# Names and version
|
||||
|
||||
!define APP_NAME "FreeCAD"
|
||||
!define APP_VERSION_NUMBER "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_PATCH}.${APP_VERSION_BUILD}"
|
||||
# For the proposed install folder we use the scheme "FreeCAD 0.18"
|
||||
# however for the Registry, we need the scheme "FreeCAD 0.18.x" in order
|
||||
# to check if it is exactly this version (to support side-by-side installations)
|
||||
!define APP_SERIES_NAME "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}"
|
||||
!define APP_SERIES_KEY "${APP_VERSION_MAJOR}${APP_VERSION_MINOR}${APP_VERSION_PATCH}${APP_VERSION_EMERGENCY}"
|
||||
!define APP_SERIES_KEY2 "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_PATCH}${APP_EMERGENCY_DOT}${APP_VERSION_EMERGENCY}"
|
||||
!define APP_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${APP_NAME}.exe"
|
||||
!define APP_DIR "${APP_NAME} ${APP_SERIES_NAME}"
|
||||
# Fixme: FC should use different preferences folder for every release
|
||||
!define APP_DIR_USERDATA ${APP_NAME}
|
||||
#!define APP_DIR_USERDATA "${APP_NAME}${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}"
|
||||
!define APP_SHORTCUT_INFO "${APP_NAME} - Your Own 3D Parametric Modeler"
|
||||
!define APP_INFO "Install/Uninstall ${APP_NAME}"
|
||||
!define APP_WEBPAGE "https://www.freecad.org/"
|
||||
!define APP_WEBPAGE_INFO "${APP_NAME} Website"
|
||||
!define APP_WIKI "https://wiki.freecad.org/Main_Page"
|
||||
!define APP_WIKI_INFO "${APP_NAME} Wiki"
|
||||
!define APP_COPYRIGHT "${APP_NAME} is Copyright © 2001-${COPYRIGHT_YEAR} by the ${APP_NAME} Team"
|
||||
|
||||
!define APP_RUN "bin\${APP_NAME}.exe"
|
||||
!define BIN_FREECAD "${APP_NAME}.exe"
|
||||
|
||||
!define APP_REGKEY "SOFTWARE\${APP_NAME}${APP_SERIES_KEY}" # like "FreeCAD0180"
|
||||
!define APP_REGKEY_SETUP "${APP_REGKEY}\Setup"
|
||||
!define APP_REGKEY_SETTINGS "${APP_REGKEY}\Settings"
|
||||
|
||||
!define APP_REGNAME_DOC "${APP_NAME}.Document"
|
||||
|
||||
!define APP_EXT ".FCStd"
|
||||
!define APP_EXT1 ".FCStd1"
|
||||
!define APP_MIME_TYPE "application/x-zip-compressed"
|
||||
|
||||
!define APP_EXT_BAK ".FCBak"
|
||||
!define APP_EXT_MACRO ".FCMacro"
|
||||
!define APP_EXT_MAT ".FCMat"
|
||||
!define APP_EXT_SCRIPT ".FCScript"
|
||||
|
||||
!define APP_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SETUP_UNINSTALLER_KEY}"
|
||||
|
||||
#--------------------------------
|
||||
# Setup settings
|
||||
|
||||
!define SETUP_EXE ${ExeFile}
|
||||
|
||||
!define SETUP_ICON "icons\FreeCAD.ico"
|
||||
!define SETUP_HEADERIMAGE "graphics\header.bmp"
|
||||
!define SETUP_WIZARDIMAGE "graphics\banner.bmp"
|
||||
!define SETUP_UNINSTALLER "Uninstall-${APP_NAME}.exe"
|
||||
!define SETUP_UNINSTALLER_KEY "${APP_NAME}${APP_SERIES_KEY}"
|
||||
|
||||
#--------------------------------
|
||||
# Variables that are shared between multiple files
|
||||
|
||||
Var APPDATemp
|
||||
Var AppPre
|
||||
var AppSubfolder
|
||||
Var AppSuff
|
||||
Var CreateDesktopIcon
|
||||
Var CreateFileAssociations
|
||||
Var OldVersionNumber
|
||||
Var Pointer
|
||||
Var Search
|
||||
Var StartmenuFolder
|
||||
Var String
|
||||
Var UserList
|
||||
Var LangName
|
||||
100
package/WindowsInstaller/include/gui.nsh
Normal file
100
package/WindowsInstaller/include/gui.nsh
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
|
||||
gui.nsh
|
||||
|
||||
Installer user interface settings
|
||||
|
||||
*/
|
||||
|
||||
#--------------------------------
|
||||
# General
|
||||
|
||||
Name "${APP_NAME} ${APP_VERSION}"
|
||||
BrandingText " "
|
||||
|
||||
#--------------------------------
|
||||
# Interface settings
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "${SETUP_ICON}"
|
||||
!define MUI_UNICON "${SETUP_ICON}"
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP "${SETUP_HEADERIMAGE}"
|
||||
!define MUI_HEADERIMAGE_RIGHT
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "${SETUP_WIZARDIMAGE}"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${SETUP_WIZARDIMAGE}"
|
||||
|
||||
#--------------------------------
|
||||
# Pages
|
||||
|
||||
# Installer
|
||||
|
||||
# Welcome page
|
||||
!define MUI_WELCOMEPAGE_TEXT $(TEXT_WELCOME)
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
# Show the license.
|
||||
!define MUI_LICENSEPAGE_BUTTON $(^NextBtn)
|
||||
!define MUI_LICENSEPAGE_TEXT_BOTTOM " "
|
||||
!insertmacro MUI_PAGE_LICENSE "${FILES_LICENSE}"
|
||||
|
||||
# Select install mode
|
||||
# set custom function for additional checks after the user selected the install mode
|
||||
# note: will not be called in silent mode
|
||||
!define MULTIUSER_PAGE_CUSTOMFUNCTION_LEAVE PostMultiUserPageInit
|
||||
!insertmacro MULTIUSER_PAGE_INSTALLMODE
|
||||
|
||||
# Specify the installation directory.
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
|
||||
# Define which components to install.
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
|
||||
# Specify where to install program shortcuts.
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${APP_DIR}"
|
||||
!insertmacro MUI_PAGE_STARTMENU ${APP_NAME} $StartmenuFolder
|
||||
|
||||
# Watch the components being installed.
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
# The option to run FreeCAD from the finish page is currently disabled because
|
||||
# it may run with Administrator privileges, therefore causing a different
|
||||
# user directory to be used. This could be fixed by creating a separate
|
||||
# process without UAC elevation.
|
||||
#!define MUI_FINISHPAGE_RUN_TEXT "$(FinishPageRun)"
|
||||
#!define MUI_FINISHPAGE_RUN "$INSTDIR\${APP_RUN}"
|
||||
|
||||
!define MUI_FINISHPAGE_SHOWREADME
|
||||
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION StartFreeCAD
|
||||
!define MUI_FINISHPAGE_SHOWREADME_TEXT $(FinishPageRun)
|
||||
!define MUI_FINISHPAGE_LINK $(TEXT_FINISH_WEBSITE)
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION "https://www.freecad.org/"
|
||||
#!define MUI_PAGE_CUSTOMFUNCTION_SHOW CheckDesktopShortcut
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
# Uninstaller
|
||||
|
||||
!insertmacro MUI_UNPAGE_WELCOME
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_COMPONENTS
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_UNPAGE_FINISH
|
||||
|
||||
#--------------------------------
|
||||
# Installer Languages
|
||||
|
||||
!include lang\TranslatedLanguages.nsh
|
||||
|
||||
#--------------------------------
|
||||
# Version information
|
||||
|
||||
VIProductVersion "${APP_VERSION_NUMBER}"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${APP_NAME}"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "${APP_DIR}.${APP_VERSION_PATCH}"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "${APP_INFO}"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${APP_VERSION}"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "${APP_COPYRIGHT}"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "${APP_NAME} Team"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" ""
|
||||
198
package/WindowsInstaller/include/init.nsh
Normal file
198
package/WindowsInstaller/include/init.nsh
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
init.nsh
|
||||
|
||||
Initialization functions
|
||||
*/
|
||||
|
||||
#--------------------------------
|
||||
# User initialization
|
||||
|
||||
Var FCLangName
|
||||
|
||||
Function InitUser
|
||||
|
||||
# Get FreeCAD language
|
||||
|
||||
ReadRegStr $FCLangName SHELL_CONTEXT "${APP_REGKEY_SETUP}" "FreeCAD Language"
|
||||
|
||||
${If} $FCLangName != ""
|
||||
StrCpy $LangName $FCLangName
|
||||
${EndIf}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
#--------------------------------
|
||||
# MultiUser custom method
|
||||
|
||||
Function PostMultiUserPageInit
|
||||
# check if this FreeCAD version is already installed
|
||||
ReadRegStr $0 SHCTX "${APP_UNINST_KEY}" "UninstallString"
|
||||
${if} $0 != ""
|
||||
# check if the uninstaller was accidentally deleted
|
||||
# if so, don't bother the user if they really want to install a new FreeCAD over an existing one
|
||||
# because they won't have a chance to deny this
|
||||
|
||||
# remove quotes from uninstaller filename
|
||||
${TrimQuotes} $0 $0
|
||||
# skip message box if uninstaller file is missing
|
||||
IfFileExists $0 0 ContinueInstall
|
||||
|
||||
# installing over an existing installation of the same FreeCAD release is not necessary
|
||||
# if the users does this, they most probably have a problem with FreeCAD that can better be solved
|
||||
# by reinstalling FreeCAD
|
||||
# for beta and other test releases over-installing can even cause errors
|
||||
MessageBox MB_YESNOCANCEL "$(AlreadyInstalled)" /SD IDCANCEL IDYES ContinueInstall IDNO BackToMuiltUserPage
|
||||
Quit
|
||||
BackToMuiltUserPage:
|
||||
Abort
|
||||
ContinueInstall:
|
||||
${endif}
|
||||
|
||||
# check if there is an existing FreeCAD installation of the same FreeCAD series
|
||||
# we usually don't release more than 10 versions so with 20 we are safe to check if a newer version is installed
|
||||
IntOp $4 ${APP_VERSION_PATCH} + 20
|
||||
${for} $5 0 $4
|
||||
ReadRegStr $0 SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}${APP_VERSION_MAJOR}${APP_VERSION_MINOR}$5" "DisplayVersion"
|
||||
# also check for an emergency release
|
||||
${if} $0 == ""
|
||||
ReadRegStr $0 SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}${APP_VERSION_MAJOR}${APP_VERSION_MINOR}$51" "DisplayVersion"
|
||||
${endif}
|
||||
${if} $0 != ""
|
||||
StrCpy $R5 $0 # store the read version number
|
||||
StrCpy $OldVersionNumber "${APP_VERSION_MAJOR}${APP_VERSION_MINOR}$5"
|
||||
# we don't stop here because we want the latest installed version
|
||||
${endif}
|
||||
${next}
|
||||
|
||||
# NSIS cannot handle numbers with leading zero, thus cut it off before comparing
|
||||
StrCpy $1 $OldVersionNumber "" 1
|
||||
StrCpy $2 ${APP_SERIES_KEY} "" 1
|
||||
${if} $1 > $2
|
||||
# store the version number and reformat it temporarily for the error message
|
||||
StrCpy $R0 $OldVersionNumber
|
||||
StrCpy $OldVersionNumber $R5
|
||||
MessageBox MB_OK|MB_ICONSTOP "$(NewerInstalled)" /SD IDOK
|
||||
StrCpy $OldVersionNumber $R0
|
||||
Quit
|
||||
${endif}
|
||||
FunctionEnd
|
||||
|
||||
|
||||
#--------------------------------
|
||||
# visible installer sections
|
||||
|
||||
Section "!${APP_NAME}" SecCore
|
||||
SectionIn RO
|
||||
SectionEnd
|
||||
|
||||
Section "$(SecFileAssocTitle)" SecFileAssoc
|
||||
StrCpy $CreateFileAssociations "true"
|
||||
SectionEnd
|
||||
|
||||
Section "$(SecDesktopTitle)" SecDesktop
|
||||
StrCpy $CreateDesktopIcon "true"
|
||||
SectionEnd
|
||||
|
||||
# Section descriptions
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "$(SecCoreDescription)"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecFileAssoc} "$(SecFileAssocDescription)"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} "$(SecDesktopDescription)"
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
|
||||
# .onInit must be here after the section definition because we have to set
|
||||
# the selection states of the dictionary sections
|
||||
Function .onInit
|
||||
|
||||
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
|
||||
${if} $R0 == "5.0" # 2000
|
||||
${orif} $R0 == "5.1" # XP
|
||||
${orif} $R0 == "5.2" # 2003
|
||||
${orif} $R0 == "6.0" # Vista
|
||||
${orif} $R0 == "6.1" # 7
|
||||
MessageBox MB_OK|MB_ICONSTOP "${APP_NAME} ${APP_VERSION} requires Windows 8 or newer." /SD IDOK
|
||||
Quit
|
||||
${endif}
|
||||
|
||||
# check if it is a 64bit system
|
||||
${if} ${RunningX64}
|
||||
SetRegView 64
|
||||
!define LIBRARY_X64
|
||||
${endif}
|
||||
|
||||
# Check that FreeCAD is not currently running
|
||||
${nsProcess::FindProcess} ${BIN_FREECAD} $R0
|
||||
# if running result is '0', if not running it is '603'
|
||||
${if} $R0 == "0"
|
||||
MessageBox MB_OK|MB_ICONSTOP "$(UnInstallRunning)" /SD IDOK
|
||||
Abort
|
||||
${endif}
|
||||
# plugin must be unloaded
|
||||
${nsProcess::Unload}
|
||||
|
||||
# initialize the multi-user installer UI
|
||||
!insertmacro MULTIUSER_INIT
|
||||
|
||||
# this can be reset to "true" in section SecDesktop
|
||||
StrCpy $CreateDesktopIcon "false"
|
||||
StrCpy $CreateFileAssociations "false"
|
||||
|
||||
${IfNot} ${Silent}
|
||||
# Show banner while installer is initializing
|
||||
Banner::show /NOUNLOAD "Checking system"
|
||||
Banner::destroy
|
||||
${EndIf}
|
||||
|
||||
# if installer runs silent the post install mode page routine has to be called here
|
||||
${If} ${Silent}
|
||||
Call PostMultiUserPageInit
|
||||
${endif}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
# this function is called at first after starting the uninstaller
|
||||
Function un.onInit
|
||||
|
||||
# Macro to investigate name of FreeCAD's preferences folders to be able remove them
|
||||
!insertmacro UnAppPreSuff $AppPre $AppSuff # macro from Utils.nsh
|
||||
|
||||
!insertmacro MULTIUSER_UNINIT
|
||||
|
||||
# Check that FreeCAD is not currently running
|
||||
${nsProcess::FindProcess} ${BIN_FREECAD} $R0
|
||||
# if running result is '0', if not running it is '603'
|
||||
${if} $R0 == "0"
|
||||
MessageBox MB_OK|MB_ICONSTOP "$(UnInstallRunning)" /SD IDOK
|
||||
Abort
|
||||
${endif}
|
||||
# plugin must be unloaded
|
||||
${nsProcess::Unload}
|
||||
|
||||
# check if it is a 64bit system
|
||||
${if} ${RunningX64}
|
||||
SetRegView 64
|
||||
${endif}
|
||||
|
||||
# Ascertain whether the user has sufficient privileges to uninstall.
|
||||
# abort when FreeCAD was installed with admin permissions but the user doesn't have administrator privileges
|
||||
ReadRegStr $0 HKLM "${APP_UNINST_KEY}" "DisplayVersion"
|
||||
${if} $0 != ""
|
||||
${andif} $MultiUser.Privileges != "Admin"
|
||||
${andif} $MultiUser.Privileges != "Power"
|
||||
MessageBox MB_OK|MB_ICONSTOP "$(UnNotAdminLabel)" /SD IDOK
|
||||
Abort
|
||||
${endif}
|
||||
# warning when FreeCAD couldn't be found in the registry
|
||||
${if} $0 == "" # check in HKCU
|
||||
ReadRegStr $0 HKCU "${APP_UNINST_KEY}" "DisplayVersion"
|
||||
${if} $0 == ""
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "$(UnNotInRegistryLabel)" /SD IDOK
|
||||
${endif}
|
||||
${endif}
|
||||
|
||||
# question message if the user really wants to uninstall FreeCAD
|
||||
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(UnReallyRemoveLabel)" /SD IDYES IDYES +2 # continue if yes
|
||||
Abort
|
||||
|
||||
FunctionEnd
|
||||
271
package/WindowsInstaller/include/utils.nsh
Normal file
271
package/WindowsInstaller/include/utils.nsh
Normal file
@@ -0,0 +1,271 @@
|
||||
# This script contains the following functions:
|
||||
#
|
||||
# - un.DelAppPathSub and UnAppPreSuff,
|
||||
# (delete the folder ~\Documents and Settings\username\Application Data\FreeCAD for all users), uses:
|
||||
# un.GetParentA
|
||||
# un.GetUsers
|
||||
# un.StrPoint
|
||||
# StrPointer
|
||||
# StrPoint
|
||||
# UnAppPreSuff
|
||||
#
|
||||
# - FileCheck (checks if a given file exists)
|
||||
#
|
||||
#--------------------------
|
||||
|
||||
!macro StrPointer FindStr SearchStr Pointer
|
||||
# searches for a string/character (SearchStr) in another string (FindStr)
|
||||
# and returns the number of the character in the FindStr where the SearchStr was found (Pointer)
|
||||
# if nothing was found or the search is impossible the Pointer is set to -1
|
||||
|
||||
StrLen $R2 "${SearchStr}"
|
||||
StrLen $R4 "${FindStr}"
|
||||
StrCpy $R5 0
|
||||
${if} $R2 == 0
|
||||
${orif} $R4 == 0
|
||||
Goto NotFound
|
||||
${endif}
|
||||
IntCmp $R4 $R2 loopA NotFound
|
||||
loopA:
|
||||
StrCpy $R3 "${FindStr}" $R2 $R5
|
||||
StrCmp $R3 "${SearchStr}" Found
|
||||
IntOp $R5 $R5 + 1
|
||||
IntCmp $R4 $R5 loopA NotFound
|
||||
Goto loopA
|
||||
Found:
|
||||
StrCpy ${Pointer} $R5
|
||||
Goto done
|
||||
NotFound:
|
||||
StrCpy ${Pointer} "-1"
|
||||
done:
|
||||
|
||||
!macroend
|
||||
|
||||
#--------------------------------
|
||||
|
||||
Function StrPoint
|
||||
!insertmacro StrPointer $String $Search $Pointer
|
||||
FunctionEnd
|
||||
|
||||
#--------------------------------
|
||||
|
||||
!macro RevStrPointer FindStr SearchStr Pointer
|
||||
# searches for a string/character (SearchStr) in another string (FindStr) in reverse order
|
||||
# and returns the number of the character in the FindStr where the SearchStr was found (Pointer)
|
||||
# if nothing was found or the search is impossible the Pointer is set to +1
|
||||
|
||||
StrLen $R2 ${SearchStr}
|
||||
StrLen $R4 ${FindStr}
|
||||
${if} $R2 == 0
|
||||
${orif} $R4 == 0
|
||||
Goto NotFound
|
||||
${endif}
|
||||
IntCmp $R4 $R2 loopA NotFound
|
||||
StrCpy $R5 "-$R2"
|
||||
loopA:
|
||||
StrCpy $R3 ${FindStr} $R2 $R5
|
||||
StrCmp $R3 ${SearchStr} Found
|
||||
IntOp $R5 $R5 - 1
|
||||
IntCmp "$R5" "-$R4" loopA NotFound
|
||||
Goto loopA
|
||||
Found:
|
||||
StrCpy ${Pointer} $R5
|
||||
Goto done
|
||||
NotFound:
|
||||
StrCpy ${Pointer} "+1"
|
||||
done:
|
||||
|
||||
!macroend
|
||||
|
||||
#--------------------------------
|
||||
|
||||
!macro AppPreSuff AppPre AppSuff
|
||||
# the APPDATA path for a local user has for WinXP and 2000 the following structure:
|
||||
# C:\Documents and Settings\username\Application Data
|
||||
# for Win Vista the structure is:
|
||||
# C:\Users\username\AppData\Roaming
|
||||
# this macro saves the "C:\Documents and Settings\" substring into the variable "AppPre"
|
||||
# and the "Application Data" substring into the variable "AppSuff"
|
||||
|
||||
# switch temporarily to local user because the all users application data path is in
|
||||
# Vista only C:\ProgramData
|
||||
SetShellVarContext current
|
||||
StrCpy $String "$APPDATA"
|
||||
Var /GLOBAL APPDATemp
|
||||
StrCpy $APPDATemp "$APPDATA"
|
||||
${If} $MultiUser.Privileges == "Admin"
|
||||
${OrIf} $MultiUser.Privileges == "Power"
|
||||
SetShellVarContext all # move back to all users
|
||||
${endif}
|
||||
StrCpy $Search "\"
|
||||
Call StrPoint # search for the first "\"
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "\"
|
||||
StrCpy $String $String "" $Pointer # cut off the part before the first "\"
|
||||
StrCpy $0 $Pointer
|
||||
Call StrPoint # search for the second "\"
|
||||
IntOp $0 $0 + $Pointer # $0 is now the pointer to the second "\" in the APPDATA string
|
||||
StrCpy ${AppPre} $APPDATemp $0 # save the part before the second "\"
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "\"
|
||||
StrCpy $String $String "" $Pointer # cut off the part before the second "\"
|
||||
Call StrPoint # search for the third "\"
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "\"
|
||||
StrCpy ${AppSuff} $String "" $Pointer # save the part after the third "\"
|
||||
|
||||
!macroend
|
||||
|
||||
#--------------------------------
|
||||
|
||||
Function un.GetParentA
|
||||
# deletes a subfolder of the APPDATA path for all users
|
||||
# used by the function "un.getUsers"
|
||||
|
||||
Exch $R0
|
||||
Push $R1
|
||||
Push $R2
|
||||
Push $R3
|
||||
StrCpy $R1 0
|
||||
StrLen $R2 $R0
|
||||
loop:
|
||||
IntOp $R1 $R1 + 1
|
||||
IntCmp $R1 $R2 get 0 get
|
||||
StrCpy $R3 $R0 1 -$R1
|
||||
StrCmp $R3 "\" get
|
||||
Goto loop
|
||||
get:
|
||||
StrCpy $R0 $R0 -$R1
|
||||
Pop $R3
|
||||
Pop $R2
|
||||
Pop $R1
|
||||
Exch $R0
|
||||
|
||||
FunctionEnd
|
||||
|
||||
#--------------------------------
|
||||
|
||||
Function un.GetUsers
|
||||
# reads the subfolders of the "Documents and Settings" folder to get a list of the users
|
||||
|
||||
StrCpy $R3 ""
|
||||
Push "$PROFILE"
|
||||
Call un.GetParentA
|
||||
Pop $R2
|
||||
StrCpy $R2 "$R2"
|
||||
FindFirst $R0 $R1 "$R2\*"
|
||||
StrCmp $R1 "" findend 0
|
||||
findloop:
|
||||
IfFileExists "$R2\$R1\*.*" 0 notDir
|
||||
StrCmp $R1 "." notDir
|
||||
StrCmp $R1 ".." notDir
|
||||
StrCmp $R1 "All Users" notDir
|
||||
StrCmp $R1 "Default User" notDir
|
||||
StrCmp $R1 "All Users.WINNT" notDir
|
||||
StrCmp $R1 "Default User.WINNT" notDir
|
||||
StrCpy $R3 "$R3|$R1"
|
||||
notDir:
|
||||
FindNext $R0 $R1
|
||||
StrCmp $R1 "" findend 0
|
||||
Goto findloop
|
||||
findend:
|
||||
FindClose $R0
|
||||
|
||||
FunctionEnd
|
||||
|
||||
#--------------------------------
|
||||
|
||||
Function un.StrPoint
|
||||
!insertmacro StrPointer $String $Search $Pointer
|
||||
FunctionEnd
|
||||
|
||||
#--------------------------------
|
||||
|
||||
!macro UnAppPreSuff AppPre AppSuff
|
||||
# the APPDATA path for a local user has for WinXP and 2000 the following structure:
|
||||
# C:\Documents and Settings\username\Application Data
|
||||
# for Win Vista the structure is:
|
||||
# C:\Users\username\AppData\Roaming
|
||||
# this macro saves the "C:\Documents and Settings\" substring into the variable "AppPre"
|
||||
# and the "Application Data" substring into the variable "AppSuff"
|
||||
|
||||
SetShellVarContext current # switch temoprarily to local user
|
||||
StrCpy $String "$APPDATA"
|
||||
StrCpy $APPDATemp "$APPDATA"
|
||||
${if} $MultiUser.Privileges == "Admin"
|
||||
${orif} $MultiUser.Privileges == "Power"
|
||||
SetShellVarContext all # move back to all users
|
||||
${endif}
|
||||
StrCpy $Search "\"
|
||||
Call un.StrPoint # search for the first "\"
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "\"
|
||||
StrCpy $String $String "" $Pointer # cut off the part before the first "\"
|
||||
StrCpy $0 $Pointer
|
||||
Call un.StrPoint # search for the second "\"
|
||||
IntOp $0 $0 + $Pointer # $0 is now the pointer to the second "\" in the APPDATA string
|
||||
StrCpy ${AppPre} $APPDATemp $0 # save the part before the second "\"
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "\"
|
||||
StrCpy $String $String "" $Pointer # cut off the part before the second "\"
|
||||
Call un.StrPoint # search for the third "\"
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "\"
|
||||
StrCpy ${AppSuff} $String "" $Pointer # save the part after the third "\"
|
||||
|
||||
!macroend
|
||||
|
||||
#--------------------------------
|
||||
|
||||
Function un.DelAppPathSub
|
||||
# deletes a subfolder of the APPDATA path for all users
|
||||
|
||||
# get list of all users
|
||||
Push $R0
|
||||
Push $R1
|
||||
Push $R2
|
||||
Push $R3
|
||||
Call un.GetUsers
|
||||
StrCpy $UserList $R3 "" 1 # cut off the "|" at the end of the list
|
||||
Pop $R3
|
||||
Pop $R2
|
||||
Pop $R1
|
||||
Pop $R0
|
||||
|
||||
# the usernames in the list of all users is separated by "|"
|
||||
loop:
|
||||
StrCpy $String "$UserList"
|
||||
StrCpy $Search "|"
|
||||
Call un.StrPoint # search for the "|"
|
||||
StrCmp $Pointer "-1" ready
|
||||
StrCpy $0 $UserList $Pointer # $0 contains now the username
|
||||
IntOp $Pointer $Pointer + 1 # jump after the "|"
|
||||
StrCpy $UserList $UserList "" $Pointer # cut off the first username in the list
|
||||
# generate the string for the current user
|
||||
# AppPre and AppSuff are generated in the macro "AppPreSuff"
|
||||
RMDir /r "$AppPre\$0\$AppSuff\$AppSubfolder" # delete the folder
|
||||
Goto loop
|
||||
ready:
|
||||
StrCpy $0 $UserList
|
||||
RMDir /r "$AppPre\$0\$AppSuff\$AppSubfolder" # delete the folder
|
||||
|
||||
FunctionEnd
|
||||
|
||||
#--------------------------------
|
||||
#source: https://nsis.sourceforge.io/Trim_quotes
|
||||
|
||||
Function TrimQuotes
|
||||
Exch $R0
|
||||
Push $R1
|
||||
|
||||
StrCpy $R1 $R0 1
|
||||
StrCmp $R1 `"` 0 +2
|
||||
StrCpy $R0 $R0 `` 1
|
||||
StrCpy $R1 $R0 1 -1
|
||||
StrCmp $R1 `"` 0 +2
|
||||
StrCpy $R0 $R0 -1
|
||||
|
||||
Pop $R1
|
||||
Exch $R0
|
||||
FunctionEnd
|
||||
|
||||
!macro _TrimQuotes Input Output
|
||||
Push `${Input}`
|
||||
Call TrimQuotes
|
||||
Pop ${Output}
|
||||
!macroend
|
||||
!define TrimQuotes `!insertmacro _TrimQuotes`
|
||||
Reference in New Issue
Block a user