home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Programming / nsis-2.46-setup.exe / Include / Memento.nsh < prev    next >
Encoding:
Text File  |  2008-03-16  |  10.4 KB  |  527 lines

  1. !verbose push
  2. !verbose 3
  3.  
  4. !include LogicLib.nsh
  5. !include Sections.nsh
  6.  
  7. !ifndef ___MEMENTO_NSH___
  8. !define ___MEMENTO_NSH___
  9.  
  10. #####################################
  11. ### Memento                       ###
  12. #####################################
  13.  
  14. /*
  15.  
  16. Memento is a set of macros that allow installers to remember user selection
  17. across separate runs of the installer. Currently, it can remember the state
  18. of sections and mark new sections as bold. In the future, it'll integrate
  19. InstallOptions and maybe even the Modern UI.
  20.  
  21. A usage example can be found in `Examples\Memento.nsi`.
  22.  
  23. */
  24.  
  25. #####################################
  26. ### Usage Instructions            ###
  27. #####################################
  28.  
  29. /*
  30.  
  31. 1. Declare usage of Memento by including Memento.nsh at the top of the script.
  32.  
  33.       !include Memento.nsh
  34.  
  35. 2. Define MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY with the a registry key
  36.    where sections' state should be saved.
  37.  
  38.       !define MEMENTO_REGISTRY_ROOT HKLM
  39.       !define MEMENTO_REGISTRY_KEY \
  40.                 Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProgram
  41.  
  42. 3. Replace Section with ${MementoSection} and SectionEnd with ${MementoSectionEnd}
  43.    for sections that whose state should be remembered by Memento.
  44.  
  45.    For sections that should be unselected by default, use ${MementoSection}'s
  46.    brother - ${MementoUnselectedSection}.
  47.  
  48.    Sections that don't already have an identifier must be assigned one.
  49.  
  50.    Section identifiers must stay the same across different versions of the
  51.    installer or their state will be forgotten.
  52.  
  53. 4. Use ${MementoSectionDone} after the last ${MementoSection}.
  54.  
  55. 5. Add a call to ${MementoSectionRestore} to .onInit to restore the state
  56.    of all sections from the registry.
  57.  
  58.       Function .onInit
  59.  
  60.         ${MementoSectionRestore}
  61.  
  62.       FunctionEnd
  63.  
  64. 6. Add a call to ${MementoSectionSave} to .onInstSuccess to save the state
  65.    of all sections to the registry.
  66.  
  67.       Function .onInstSuccess
  68.  
  69.         ${MementoSectionSave}
  70.  
  71.       FunctionEnd
  72.  
  73. 7. Tattoo the location of the chosen registry key on your arm.
  74.  
  75. */
  76.  
  77. #####################################
  78. ### User API                      ###
  79. #####################################
  80.  
  81. ;
  82. ; ${MementoSection}
  83. ;
  84. ;   Defines a section whose state is remembered by Memento.
  85. ;
  86. ;   Usage is similar to Section.
  87. ;
  88. ;     ${MementoSection} "name" "some_id"
  89. ;
  90.  
  91. !define MementoSection "!insertmacro MementoSection"
  92.  
  93. ;
  94. ; ${MementoSectionEnd}
  95. ;
  96. ;   Ends a section previously opened using ${MementoSection}.
  97. ;
  98. ;   Usage is similar to SectionEnd.
  99. ;
  100. ;     ${MementoSection} "name" "some_id"
  101. ;        # some code...
  102. ;     ${MementoSectionEnd}
  103. ;
  104.  
  105. ;
  106. ; ${MementoUnselectedSection}
  107. ;
  108. ;   Defines a section whose state is remembered by Memento and is
  109. ;   unselected by default.
  110. ;
  111. ;   Usage is similar to Section with the /o switch.
  112. ;
  113. ;     ${MementoUnselectedSection} "name" "some_id"
  114. ;
  115.  
  116. !define MementoUnselectedSection "!insertmacro MementoUnselectedSection"
  117.  
  118. ;
  119. ; ${MementoSectionEnd}
  120. ;
  121. ;   Ends a section previously opened using ${MementoSection}.
  122. ;
  123. ;   Usage is similar to SectionEnd.
  124. ;
  125. ;     ${MementoSection} "name" "some_id"
  126. ;        # some code...
  127. ;     ${MementoSectionEnd}
  128. ;
  129.  
  130. !define MementoSectionEnd "!insertmacro MementoSectionEnd"
  131.  
  132. ;
  133. ; ${MementoSectionDone}
  134. ;
  135. ;   Used after all ${MementoSection} have been set.
  136. ;
  137. ;     ${MementoSection} "name1" "some_id1"
  138. ;        # some code...
  139. ;     ${MementoSectionEnd}
  140. ;
  141. ;     ${MementoSection} "name2" "some_id2"
  142. ;        # some code...
  143. ;     ${MementoSectionEnd}
  144. ;
  145. ;     ${MementoSection} "name3" "some_id3"
  146. ;        # some code...
  147. ;     ${MementoSectionEnd}
  148. ;
  149. ;     ${MementoSectionDone}
  150. ;
  151.  
  152. !define MementoSectionDone "!insertmacro MementoSectionDone"
  153.  
  154. ;
  155. ; ${MementoSectionRestore}
  156. ;
  157. ;   Restores the state of all Memento sections from the registry.
  158. ;
  159. ;   Commonly used in .onInit.
  160. ;
  161. ;     Function .onInit
  162. ;
  163. ;       ${MementoSectionRestore}
  164. ;
  165. ;     FunctionEnd
  166. ;
  167.  
  168. !define MementoSectionRestore "!insertmacro MementoSectionRestore"
  169.  
  170. ;
  171. ; ${MementoSectionSave}
  172. ;
  173. ;   Saves the state of all Memento sections to the registry.
  174. ;
  175. ;   Commonly used in .onInstSuccess.
  176. ;
  177. ;     Function .onInstSuccess
  178. ;
  179. ;       ${MementoSectionSave}
  180. ;
  181. ;     FunctionEnd
  182. ;
  183.  
  184. !define MementoSectionSave "!insertmacro MementoSectionSave"
  185.  
  186.  
  187. #####################################
  188. ### Internal Defines              ###
  189. #####################################
  190.  
  191. !define __MementoSectionIndex 1
  192.  
  193. #####################################
  194. ### Internal Macros               ###
  195. #####################################
  196.  
  197. !macro __MementoCheckSettings
  198.  
  199.   !ifndef MEMENTO_REGISTRY_ROOT | MEMENTO_REGISTRY_KEY
  200.  
  201.     !error "MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY must be defined before using any of Memento's macros"
  202.  
  203.   !endif
  204.  
  205. !macroend
  206.  
  207. !macro __MementoSection flags name id
  208.  
  209.   !insertmacro __MementoCheckSettings
  210.  
  211.   !ifndef __MementoSectionIndex
  212.  
  213.     !error "MementoSectionDone already used!"
  214.  
  215.   !endif
  216.  
  217.   !define __MementoSectionLastSectionId `${id}`
  218.  
  219.   !verbose pop
  220.  
  221.   Section ${flags} `${name}` `${id}`
  222.  
  223.   !verbose push
  224.   !verbose 3
  225.  
  226. !macroend
  227.  
  228. #####################################
  229. ### User Macros                   ###
  230. #####################################
  231.  
  232. !macro MementoSection name id
  233.  
  234.   !verbose push
  235.   !verbose 3
  236.  
  237.   !insertmacro __MementoSection "" `${name}` `${id}`
  238.  
  239.   !verbose pop
  240.  
  241. !macroend
  242.  
  243. !macro MementoUnselectedSection name id
  244.  
  245.   !verbose push
  246.   !verbose 3
  247.  
  248.   !insertmacro __MementoSection /o `${name}` `${id}`
  249.  
  250.   !define __MementoSectionUnselected
  251.  
  252.   !verbose pop
  253.  
  254. !macroend
  255.  
  256. !macro MementoSectionEnd
  257.  
  258.   SectionEnd
  259.  
  260.   !verbose push
  261.   !verbose 3
  262.  
  263.   !insertmacro __MementoCheckSettings
  264.  
  265.   !ifndef __MementoSectionIndex
  266.  
  267.     !error "MementoSectionDone already used!"
  268.  
  269.   !endif
  270.  
  271.   !define /MATH __MementoSectionIndexNext \
  272.       ${__MementoSectionIndex} + 1
  273.  
  274.   Function __MementoSectionMarkNew${__MementoSectionIndex}
  275.  
  276.     ClearErrors
  277.     ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`
  278.  
  279.     ${If} ${Errors}
  280.  
  281.       !insertmacro SetSectionFlag `${${__MementoSectionLastSectionId}}` ${SF_BOLD}
  282.  
  283.     ${EndIf}
  284.  
  285.     GetFunctionAddress $0 __MementoSectionMarkNew${__MementoSectionIndexNext}
  286.     Goto $0
  287.  
  288.   FunctionEnd
  289.  
  290.   Function __MementoSectionRestoreStatus${__MementoSectionIndex}
  291.  
  292.     ClearErrors
  293.     ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`
  294.  
  295.     !ifndef __MementoSectionUnselected
  296.  
  297.       ${If} ${Errors}
  298.       ${OrIf} $0 != 0
  299.  
  300.         !insertmacro SelectSection `${${__MementoSectionLastSectionId}}`
  301.  
  302.       ${Else}
  303.  
  304.         !insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`
  305.  
  306.       ${EndIf}
  307.  
  308.     !else
  309.  
  310.       !undef __MementoSectionUnselected
  311.  
  312.       ${If} ${Errors}
  313.       ${OrIf} $0 == 0
  314.  
  315.         !insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`
  316.  
  317.       ${Else}
  318.  
  319.         !insertmacro SelectSection `${${__MementoSectionLastSectionId}}`
  320.  
  321.       ${EndIf}
  322.  
  323.     !endif
  324.  
  325.     GetFunctionAddress $0 __MementoSectionRestoreStatus${__MementoSectionIndexNext}
  326.     Goto $0
  327.  
  328.   FunctionEnd
  329.  
  330.   Function __MementoSectionSaveStatus${__MementoSectionIndex}
  331.  
  332.     ${If} ${SectionIsSelected} `${${__MementoSectionLastSectionId}}`
  333.  
  334.       WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 1
  335.  
  336.     ${Else}
  337.  
  338.       WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 0
  339.  
  340.     ${EndIf}
  341.  
  342.     GetFunctionAddress $0 __MementoSectionSaveStatus${__MementoSectionIndexNext}
  343.     Goto $0
  344.  
  345.   FunctionEnd
  346.  
  347.   !undef __MementoSectionIndex
  348.   !define __MementoSectionIndex ${__MementoSectionIndexNext}
  349.   !undef __MementoSectionIndexNext
  350.  
  351.   !undef __MementoSectionLastSectionId
  352.  
  353.   !verbose pop
  354.  
  355. !macroend
  356.  
  357. !macro MementoSectionDone
  358.  
  359.   !verbose push
  360.   !verbose 3
  361.  
  362.   !insertmacro __MementoCheckSettings
  363.  
  364.   Function __MementoSectionMarkNew${__MementoSectionIndex}
  365.   FunctionEnd
  366.  
  367.   Function __MementoSectionRestoreStatus${__MementoSectionIndex}
  368.   FunctionEnd
  369.  
  370.   Function __MementoSectionSaveStatus${__MementoSectionIndex}
  371.   FunctionEnd
  372.  
  373.   !undef __MementoSectionIndex
  374.  
  375.   !verbose pop
  376.  
  377. !macroend
  378.  
  379. !macro MementoSectionRestore
  380.  
  381.   !verbose push
  382.   !verbose 3
  383.  
  384.   !insertmacro __MementoCheckSettings
  385.  
  386.   Push $0
  387.   Push $1
  388.   Push $2
  389.   Push $3
  390.  
  391.     # check for first usage
  392.  
  393.     ClearErrors
  394.  
  395.     ReadRegStr $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed
  396.  
  397.     ${If} ${Errors}
  398.  
  399.       # use script defaults on first run
  400.       Goto done
  401.  
  402.     ${EndIf}
  403.  
  404.     # mark new components in bold
  405.     
  406.     Call __MementoSectionMarkNew1
  407.  
  408.     # mark section groups in bold
  409.  
  410.     StrCpy $0 0
  411.     StrCpy $1 ""
  412.     StrCpy $2 ""
  413.     StrCpy $3 ""
  414.  
  415.     loop:
  416.  
  417.       ClearErrors
  418.  
  419.       ${If} ${SectionIsBold} $0
  420.  
  421.         ${If} $1 != ""
  422.  
  423.           !insertmacro SetSectionFlag $1 ${SF_BOLD}
  424.  
  425.         ${EndIf}
  426.  
  427.         ${If} $2 != ""
  428.  
  429.           !insertmacro SetSectionFlag $2 ${SF_BOLD}
  430.  
  431.         ${EndIf}
  432.  
  433.         ${If} $3 != ""
  434.  
  435.           !insertmacro SetSectionFlag $3 ${SF_BOLD}
  436.  
  437.         ${EndIf}
  438.  
  439.       ${ElseIf} ${Errors}
  440.  
  441.         Goto loop_end
  442.  
  443.       ${EndIf}
  444.  
  445.       ${If} ${SectionIsSectionGroup} $0
  446.  
  447.         ${If} $1 == ""
  448.  
  449.           StrCpy $1 $0
  450.  
  451.         ${ElseIf} $2 == ""
  452.  
  453.           StrCpy $2 $0
  454.  
  455.         ${ElseIf} $3 == ""
  456.  
  457.           StrCpy $3 $0
  458.  
  459.         ${EndIf}
  460.  
  461.       ${EndIf}
  462.  
  463.       ${If} ${SectionIsSectionGroupEnd} $0
  464.  
  465.         ${If} $3 != ""
  466.  
  467.           StrCpy $3 ""
  468.  
  469.         ${ElseIf} $2 != ""
  470.  
  471.           StrCpy $2 ""
  472.  
  473.         ${ElseIf} $1 != ""
  474.  
  475.           StrCpy $1 ""
  476.  
  477.         ${EndIf}
  478.  
  479.       ${EndIf}
  480.  
  481.       IntOp $0 $0 + 1
  482.  
  483.     Goto loop
  484.     loop_end:
  485.  
  486.     # restore sections' status
  487.  
  488.     Call __MementoSectionRestoreStatus1
  489.  
  490.   # all done
  491.  
  492.   done:
  493.  
  494.   Pop $3
  495.   Pop $2
  496.   Pop $1
  497.   Pop $0
  498.  
  499.   !verbose pop
  500.  
  501. !macroend
  502.  
  503. !macro MementoSectionSave
  504.  
  505.   !verbose push
  506.   !verbose 3
  507.  
  508.   !insertmacro __MementoCheckSettings
  509.  
  510.   Push $0
  511.  
  512.     WriteRegStr ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed ""
  513.   
  514.     Call __MementoSectionSaveStatus1
  515.  
  516.   Pop $0
  517.  
  518.   !verbose pop
  519.  
  520. !macroend
  521.  
  522.  
  523.  
  524. !endif # ___MEMENTO_NSH___
  525.  
  526. !verbose pop
  527.