123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- !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"
- #####################################
- ### Internal Defines ###
- #####################################
- !define __MementoSectionIndex 1
- #####################################
- ### Internal Macros ###
- #####################################
- !macro __MementoCheckSettings
- !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
- !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
- ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`
- ${If} ${Errors}
- !insertmacro SetSectionFlag `${${__MementoSectionLastSectionId}}` ${SF_BOLD}
- ${EndIf}
- GetFunctionAddress $0 __MementoSectionMarkNew${__MementoSectionIndexNext}
- Goto $0
- FunctionEnd
- Function __MementoSectionRestoreStatus${__MementoSectionIndex}
- ClearErrors
- ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__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}}`
- WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 1
- ${Else}
- WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__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
- ReadRegStr $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed
- ${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
- WriteRegStr ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed ""
-
- Call __MementoSectionSaveStatus1
- Pop $0
- !verbose pop
- !macroend
- !endif # ___MEMENTO_NSH___
- !verbose pop
|