554 lines
10 KiB
Plaintext
554 lines
10 KiB
Plaintext
!verbose push
|
|
!verbose 3
|
|
|
|
!include LogicLib.nsh
|
|
!include Sections.nsh
|
|
|
|
!ifndef ___MEMENTO_NSH___
|
|
!define ___MEMENTO_NSH___
|
|
|
|
#####################################
|
|
### Memento ###
|
|
#####################################
|
|
|
|
/*
|
|
|
|
Memento is a set of macros that allow installers to remember user selection
|
|
across separate runs of the installer. Currently, it can remember the state
|
|
of sections and mark new sections as bold. In the future, it'll integrate
|
|
InstallOptions and maybe even the Modern UI.
|
|
|
|
A usage example can be found in `Examples\Memento.nsi`.
|
|
|
|
*/
|
|
|
|
#####################################
|
|
### Usage Instructions ###
|
|
#####################################
|
|
|
|
/*
|
|
|
|
1. Declare usage of Memento by including Memento.nsh at the top of the script.
|
|
|
|
!include Memento.nsh
|
|
|
|
2. Define MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY with the a registry key
|
|
where sections' state should be saved.
|
|
|
|
!define MEMENTO_REGISTRY_ROOT HKLM
|
|
!define MEMENTO_REGISTRY_KEY \
|
|
Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProgram
|
|
|
|
3. Replace Section with ${MementoSection} and SectionEnd with ${MementoSectionEnd}
|
|
for sections that whose state should be remembered by Memento.
|
|
|
|
For sections that should be unselected by default, use ${MementoSection}'s
|
|
brother - ${MementoUnselectedSection}.
|
|
|
|
Sections that don't already have an identifier must be assigned one.
|
|
|
|
Section identifiers must stay the same across different versions of the
|
|
installer or their state will be forgotten.
|
|
|
|
4. Use ${MementoSectionDone} after the last ${MementoSection}.
|
|
|
|
5. Add a call to ${MementoSectionRestore} to .onInit to restore the state
|
|
of all sections from the registry.
|
|
|
|
Function .onInit
|
|
|
|
${MementoSectionRestore}
|
|
|
|
FunctionEnd
|
|
|
|
6. Add a call to ${MementoSectionSave} to .onInstSuccess to save the state
|
|
of all sections to the registry.
|
|
|
|
Function .onInstSuccess
|
|
|
|
${MementoSectionSave}
|
|
|
|
FunctionEnd
|
|
|
|
7. Tattoo the location of the chosen registry key on your arm.
|
|
|
|
*/
|
|
|
|
#####################################
|
|
### User API ###
|
|
#####################################
|
|
|
|
;
|
|
; ${MementoSection}
|
|
;
|
|
; Defines a section whose state is remembered by Memento.
|
|
;
|
|
; Usage is similar to Section.
|
|
;
|
|
; ${MementoSection} "name" "some_id"
|
|
;
|
|
|
|
!define MementoSection "!insertmacro MementoSection"
|
|
|
|
;
|
|
; ${MementoSectionEnd}
|
|
;
|
|
; Ends a section previously opened using ${MementoSection}.
|
|
;
|
|
; Usage is similar to SectionEnd.
|
|
;
|
|
; ${MementoSection} "name" "some_id"
|
|
; # some code...
|
|
; ${MementoSectionEnd}
|
|
;
|
|
|
|
;
|
|
; ${MementoUnselectedSection}
|
|
;
|
|
; Defines a section whose state is remembered by Memento and is
|
|
; unselected by default.
|
|
;
|
|
; Usage is similar to Section with the /o switch.
|
|
;
|
|
; ${MementoUnselectedSection} "name" "some_id"
|
|
;
|
|
|
|
!define MementoUnselectedSection "!insertmacro MementoUnselectedSection"
|
|
|
|
;
|
|
; ${MementoSectionEnd}
|
|
;
|
|
; Ends a section previously opened using ${MementoSection}.
|
|
;
|
|
; Usage is similar to SectionEnd.
|
|
;
|
|
; ${MementoSection} "name" "some_id"
|
|
; # some code...
|
|
; ${MementoSectionEnd}
|
|
;
|
|
|
|
!define MementoSectionEnd "!insertmacro MementoSectionEnd"
|
|
|
|
;
|
|
; ${MementoSectionDone}
|
|
;
|
|
; Used after all ${MementoSection} have been set.
|
|
;
|
|
; ${MementoSection} "name1" "some_id1"
|
|
; # some code...
|
|
; ${MementoSectionEnd}
|
|
;
|
|
; ${MementoSection} "name2" "some_id2"
|
|
; # some code...
|
|
; ${MementoSectionEnd}
|
|
;
|
|
; ${MementoSection} "name3" "some_id3"
|
|
; # some code...
|
|
; ${MementoSectionEnd}
|
|
;
|
|
; ${MementoSectionDone}
|
|
;
|
|
|
|
!define MementoSectionDone "!insertmacro MementoSectionDone"
|
|
|
|
;
|
|
; ${MementoSectionRestore}
|
|
;
|
|
; Restores the state of all Memento sections from the registry.
|
|
;
|
|
; Commonly used in .onInit.
|
|
;
|
|
; Function .onInit
|
|
;
|
|
; ${MementoSectionRestore}
|
|
;
|
|
; FunctionEnd
|
|
;
|
|
|
|
!define MementoSectionRestore "!insertmacro MementoSectionRestore"
|
|
|
|
;
|
|
; ${MementoSectionSave}
|
|
;
|
|
; Saves the state of all Memento sections to the registry.
|
|
;
|
|
; Commonly used in .onInstSuccess.
|
|
;
|
|
; Function .onInstSuccess
|
|
;
|
|
; ${MementoSectionSave}
|
|
;
|
|
; FunctionEnd
|
|
;
|
|
|
|
!define MementoSectionSave "!insertmacro MementoSectionSave"
|
|
|
|
;
|
|
; MementoSection<ReadWrite><Int|Marker>
|
|
;
|
|
; Replaceable macros that allow custom storage methods to be used.
|
|
;
|
|
|
|
!ifmacrondef MementoSectionReadInt
|
|
!define __MementoSectionStdRegReadWrite
|
|
|
|
!macro MementoSectionReadInt outvar name
|
|
ReadRegDWord ${outvar} ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection${name}`
|
|
!macroend
|
|
|
|
!macro MementoSectionWriteInt name val
|
|
WriteRegDWord ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection${name}` `${val}`
|
|
!macroend
|
|
|
|
!macro MementoSectionReadMarker outvar name
|
|
ReadRegStr ${outvar} ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection${name}`
|
|
!macroend
|
|
|
|
!macro MementoSectionWriteMarker name
|
|
WriteRegStr ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection${name}` ``
|
|
!macroend
|
|
|
|
!endif
|
|
|
|
#####################################
|
|
### Internal Defines ###
|
|
#####################################
|
|
|
|
!define __MementoSectionIndex 1
|
|
|
|
#####################################
|
|
### Internal Macros ###
|
|
#####################################
|
|
|
|
!macro __MementoCheckSettings
|
|
|
|
!ifdef __MementoSectionStdRegReadWrite
|
|
!ifndef MEMENTO_REGISTRY_ROOT | MEMENTO_REGISTRY_KEY
|
|
|
|
!error "MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY must be defined before using any of Memento's macros"
|
|
|
|
!endif
|
|
!endif
|
|
|
|
!macroend
|
|
|
|
!macro __MementoSection flags name id
|
|
|
|
!insertmacro __MementoCheckSettings
|
|
|
|
!ifndef __MementoSectionIndex
|
|
|
|
!error "MementoSectionDone already used!"
|
|
|
|
!endif
|
|
|
|
!define __MementoSectionLastSectionId `${id}`
|
|
|
|
!verbose pop
|
|
|
|
Section ${flags} `${name}` `${id}`
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!macroend
|
|
|
|
#####################################
|
|
### User Macros ###
|
|
#####################################
|
|
|
|
!macro MementoSection name id
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!insertmacro __MementoSection "" `${name}` `${id}`
|
|
|
|
!verbose pop
|
|
|
|
!macroend
|
|
|
|
!macro MementoUnselectedSection name id
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!insertmacro __MementoSection /o `${name}` `${id}`
|
|
|
|
!define __MementoSectionUnselected
|
|
|
|
!verbose pop
|
|
|
|
!macroend
|
|
|
|
!macro MementoSectionEnd
|
|
|
|
SectionEnd
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!insertmacro __MementoCheckSettings
|
|
|
|
!ifndef __MementoSectionIndex
|
|
|
|
!error "MementoSectionDone already used!"
|
|
|
|
!endif
|
|
|
|
!define /MATH __MementoSectionIndexNext \
|
|
${__MementoSectionIndex} + 1
|
|
|
|
Function __MementoSectionMarkNew${__MementoSectionIndex}
|
|
|
|
ClearErrors
|
|
!insertmacro MementoSectionReadInt $0 `_${__MementoSectionLastSectionId}`
|
|
|
|
${If} ${Errors}
|
|
|
|
!insertmacro SetSectionFlag `${${__MementoSectionLastSectionId}}` ${SF_BOLD}
|
|
|
|
${EndIf}
|
|
|
|
GetFunctionAddress $0 __MementoSectionMarkNew${__MementoSectionIndexNext}
|
|
Goto $0
|
|
|
|
FunctionEnd
|
|
|
|
Function __MementoSectionRestoreStatus${__MementoSectionIndex}
|
|
|
|
ClearErrors
|
|
!insertmacro MementoSectionReadInt $0 `_${__MementoSectionLastSectionId}`
|
|
|
|
!ifndef __MementoSectionUnselected
|
|
|
|
${If} ${Errors}
|
|
${OrIf} $0 != 0
|
|
|
|
!insertmacro SelectSection `${${__MementoSectionLastSectionId}}`
|
|
|
|
${Else}
|
|
|
|
!insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`
|
|
|
|
${EndIf}
|
|
|
|
!else
|
|
|
|
!undef __MementoSectionUnselected
|
|
|
|
${If} ${Errors}
|
|
${OrIf} $0 == 0
|
|
|
|
!insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`
|
|
|
|
${Else}
|
|
|
|
!insertmacro SelectSection `${${__MementoSectionLastSectionId}}`
|
|
|
|
${EndIf}
|
|
|
|
!endif
|
|
|
|
GetFunctionAddress $0 __MementoSectionRestoreStatus${__MementoSectionIndexNext}
|
|
Goto $0
|
|
|
|
FunctionEnd
|
|
|
|
Function __MementoSectionSaveStatus${__MementoSectionIndex}
|
|
|
|
${If} ${SectionIsSelected} `${${__MementoSectionLastSectionId}}`
|
|
|
|
!insertmacro MementoSectionWriteInt `_${__MementoSectionLastSectionId}` 1
|
|
|
|
${Else}
|
|
|
|
!insertmacro MementoSectionWriteInt `_${__MementoSectionLastSectionId}` 0
|
|
|
|
${EndIf}
|
|
|
|
GetFunctionAddress $0 __MementoSectionSaveStatus${__MementoSectionIndexNext}
|
|
Goto $0
|
|
|
|
FunctionEnd
|
|
|
|
!undef __MementoSectionIndex
|
|
!define __MementoSectionIndex ${__MementoSectionIndexNext}
|
|
!undef __MementoSectionIndexNext
|
|
|
|
!undef __MementoSectionLastSectionId
|
|
|
|
!verbose pop
|
|
|
|
!macroend
|
|
|
|
!macro MementoSectionDone
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!insertmacro __MementoCheckSettings
|
|
|
|
Function __MementoSectionMarkNew${__MementoSectionIndex}
|
|
FunctionEnd
|
|
|
|
Function __MementoSectionRestoreStatus${__MementoSectionIndex}
|
|
FunctionEnd
|
|
|
|
Function __MementoSectionSaveStatus${__MementoSectionIndex}
|
|
FunctionEnd
|
|
|
|
!undef __MementoSectionIndex
|
|
|
|
!verbose pop
|
|
|
|
!macroend
|
|
|
|
!macro MementoSectionRestore
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!insertmacro __MementoCheckSettings
|
|
|
|
Push $0
|
|
Push $1
|
|
Push $2
|
|
Push $3
|
|
|
|
# check for first usage
|
|
|
|
ClearErrors
|
|
!insertmacro MementoSectionReadMarker $0 `Used`
|
|
|
|
${If} ${Errors}
|
|
|
|
# use script defaults on first run
|
|
Goto done
|
|
|
|
${EndIf}
|
|
|
|
# mark new components in bold
|
|
|
|
Call __MementoSectionMarkNew1
|
|
|
|
# mark section groups in bold
|
|
|
|
StrCpy $0 0
|
|
StrCpy $1 ""
|
|
StrCpy $2 ""
|
|
StrCpy $3 ""
|
|
|
|
loop:
|
|
|
|
ClearErrors
|
|
|
|
${If} ${SectionIsBold} $0
|
|
|
|
${If} $1 != ""
|
|
|
|
!insertmacro SetSectionFlag $1 ${SF_BOLD}
|
|
|
|
${EndIf}
|
|
|
|
${If} $2 != ""
|
|
|
|
!insertmacro SetSectionFlag $2 ${SF_BOLD}
|
|
|
|
${EndIf}
|
|
|
|
${If} $3 != ""
|
|
|
|
!insertmacro SetSectionFlag $3 ${SF_BOLD}
|
|
|
|
${EndIf}
|
|
|
|
${ElseIf} ${Errors}
|
|
|
|
Goto loop_end
|
|
|
|
${EndIf}
|
|
|
|
${If} ${SectionIsSectionGroup} $0
|
|
|
|
${If} $1 == ""
|
|
|
|
StrCpy $1 $0
|
|
|
|
${ElseIf} $2 == ""
|
|
|
|
StrCpy $2 $0
|
|
|
|
${ElseIf} $3 == ""
|
|
|
|
StrCpy $3 $0
|
|
|
|
${EndIf}
|
|
|
|
${EndIf}
|
|
|
|
${If} ${SectionIsSectionGroupEnd} $0
|
|
|
|
${If} $3 != ""
|
|
|
|
StrCpy $3 ""
|
|
|
|
${ElseIf} $2 != ""
|
|
|
|
StrCpy $2 ""
|
|
|
|
${ElseIf} $1 != ""
|
|
|
|
StrCpy $1 ""
|
|
|
|
${EndIf}
|
|
|
|
${EndIf}
|
|
|
|
IntOp $0 $0 + 1
|
|
|
|
Goto loop
|
|
loop_end:
|
|
|
|
# restore sections' status
|
|
|
|
Call __MementoSectionRestoreStatus1
|
|
|
|
# all done
|
|
|
|
done:
|
|
|
|
Pop $3
|
|
Pop $2
|
|
Pop $1
|
|
Pop $0
|
|
|
|
!verbose pop
|
|
|
|
!macroend
|
|
|
|
!macro MementoSectionSave
|
|
|
|
!verbose push
|
|
!verbose 3
|
|
|
|
!insertmacro __MementoCheckSettings
|
|
|
|
Push $0
|
|
|
|
!insertmacro MementoSectionWriteMarker `Used`
|
|
|
|
Call __MementoSectionSaveStatus1
|
|
|
|
Pop $0
|
|
|
|
!verbose pop
|
|
|
|
!macroend
|
|
|
|
|
|
|
|
!endif # ___MEMENTO_NSH___
|
|
|
|
!verbose pop
|