헬마입니다.

이번엔 섹션들을 다루는데 상당히 필수적으로 포함시키는 Sections.nsh 파일에 대해 한번 몇가지 적어볼까 합니다.

일단 이 파일에는 그저 섹션과 인스톨타입에 대해 정의되어 있는 것이 전부는 아닙니다. 에를 들면 섹션이 선택되어 있는지 이런 것들을 확인할 때 이 파일에 포함된 매크로를 사용할 수 있습니다.

;--------------------------------
이파일이 포함되어 있는지 확인하기 위한 것 입니다.
!ifndef SECTIONS_INCLUDED
!define SECTIONS_INCLUDED
;--------------------------------

SectionGetFlags 등의 함수에서 사용하는 플래그 값들입니다. 이 값들은 IntOp 등의 명령을 이용해 조합해서 사용할 수 있습니다.

# section or section group is selected
!define SF_SELECTED   1  ; 선택됨
# section group
!define SF_SECGRP     2 ; 그룹의 시작
!define SF_SUBSEC     2  # deprecated
# section group end marker
!define SF_SECGRPEND  4 ; 그룹의 끝
!define SF_SUBSECEND  4  # deprecated
# bold text (Section !blah)
!define SF_BOLD       8 ; 섹션 이름이 굵은 글씨
# read only (SectionIn RO)
!define SF_RO         16 ; 읽기 전용
# expanded section group (SectionGroup /e blah)
!define SF_EXPAND     32 ; 섹션 그룹이 펼쳐져 있음
# section group is partially selected
!define SF_PSELECTED  64  # internal ; 그룹 안에 섹션들이 일부만 선택되어 있음
# internal
!define SF_TOGGLED    128 # internal
!define SF_NAMECHG    256 # internal

# mask to toggle off the selected flag
!define SECTION_OFF   0xFFFFFFFE ; 모든 플래그를 끕니다.

모든 플래그를 끄는 이 값이 존재하는 이유는 NSIS의 파일 속성 변경할 때 모든 플래그를 끄는 값이 있는 것과 마찬가지 이유입니다. 즉, NSIS는 특정 플래그만 끄는 것은 불가능합니다.
  따라서 그런 조작을 하려면 일단 모든 플래그를 끄고 특정 플래그만 껏을때의 플래그로 설정하는 방법을 사용해야합니다.

;--------------------------------

; Select / unselect / reserve section

!macro SelectSection SECTION

  Push $0
  SectionGetFlags "${SECTION}" $0
  IntOp $0 $0 | ${SF_SELECTED}
  SectionSetFlags "${SECTION}" $0
  Pop $0

!macroend

지정한 섹션(섹션을 설정할 때 사용한 섹션 인덱스를 넣어줍니다.) 을 선택 상태로 변경합니다.

!macro UnselectSection SECTION

  Push $0
  SectionGetFlags "${SECTION}" $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags "${SECTION}" $0
  Pop $0

!macroend

지정한 섹션(섹션을 설정할 때 사용한 섹션 인덱스를 넣어줍니다.) 을 선택해제 상태로 변경합니다.

; If section selected, will unselect, if unselected, will select

!macro ReverseSection SECTION

  Push $0
  SectionGetFlags "${SECTION}" $0
  IntOp $0 $0 ^ ${SF_SELECTED}
  SectionSetFlags "${SECTION}" $0
  Pop $0

!macroend

지정한 섹션(섹션을 설정할 때 사용한 섹션 인덱스를 넣어줍니다.) 을 선택되었다면 해제로, 해제되었다면 선택상태로 바꿉니다.

예)
Section 'aaa' bbb
SectionEnd

bbb -> 이게 섹션 인덱스 입니다.
!insertmacro ReverseSection bbb
이런식으로 사용하면 됩니다.

;--------------------------------
여기는 라디오 버튼처럼 섹션들을 묶어주는 기능을 하는 매크로입니다.
이에 대한 글은 이미 에전에 올린적이 있으니 따로 적지 않겠습니다.

; Macros for mutually exclusive section selection
; Written by Tim Gallagher
;
; See one-section.nsi for an example of usage

; Starts the Radio Button Block
; You should pass a variable that keeps the selected section
; as the first parameter for this macro. This variable should
; be initialized to the default section's index.
;
; As this macro uses $R0 and $R1 you can't use those two as the
; varible which will keep the selected section.

!macro StartRadioButtons var

  !define StartRadioButtons_Var "${var}"

  Push $R0
 
  SectionGetFlags "${StartRadioButtons_Var}" $R0
  IntOp $R0 $R0 & ${SECTION_OFF}
  SectionSetFlags "${StartRadioButtons_Var}" $R0
 
  Push $R1
 
  StrCpy $R1 "${StartRadioButtons_Var}"
 
!macroend

; A radio button

!macro RadioButton SECTION_NAME

  SectionGetFlags ${SECTION_NAME} $R0
  IntOp $R0 $R0 & ${SF_SELECTED}
  IntCmp $R0 ${SF_SELECTED} 0 +2 +2
  StrCpy "${StartRadioButtons_Var}" ${SECTION_NAME}

!macroend

; Ends the radio button block

!macro EndRadioButtons
 
  StrCmp $R1 "${StartRadioButtons_Var}" 0 +4 ; selection hasn't changed
  SectionGetFlags "${StartRadioButtons_Var}" $R0
  IntOp $R0 $R0 | ${SF_SELECTED}
  SectionSetFlags "${StartRadioButtons_Var}" $R0

  Pop $R1
  Pop $R0
 
  !undef StartRadioButtons_Var

!macroend

;--------------------------------

; These are two macros you can use to set a Section in an InstType
; or clear it from an InstType.
;
; Written by Robert Kehl
;
; For details, see http://nsis.sourceforge.net/wiki/SetSectionInInstType%2C_ClearSectionInInstType
;
; Use the defines below for the WANTED_INSTTYPE paramter.

!define INSTTYPE_1 1
!define INSTTYPE_2 2
!define INSTTYPE_3 4
!define INSTTYPE_4 8
!define INSTTYPE_5 16
!define INSTTYPE_6 32
!define INSTTYPE_7 64
!define INSTTYPE_8 128
!define INSTTYPE_9 256
!define INSTTYPE_10 512
!define INSTTYPE_11 1024
!define INSTTYPE_12 2048
!define INSTTYPE_13 4096
!define INSTTYPE_14 8192
!define INSTTYPE_15 16384
!define INSTTYPE_16 32768
!define INSTTYPE_17 65536
!define INSTTYPE_18 131072
!define INSTTYPE_19 262144
!define INSTTYPE_20 524288
!define INSTTYPE_21 1048576
!define INSTTYPE_22 2097152
!define INSTTYPE_23 4194304
!define INSTTYPE_24 8388608
!define INSTTYPE_25 16777216
!define INSTTYPE_26 33554432
!define INSTTYPE_27 67108864
!define INSTTYPE_28 134217728
!define INSTTYPE_29 268435456
!define INSTTYPE_30 536870912
!define INSTTYPE_31 1073741824
!define INSTTYPE_32 2147483648

!macro SetSectionInInstType SECTION_NAME WANTED_INSTTYPE

  Push $0
  SectionGetInstTypes "${SECTION_NAME}" $0
  IntOp $0 $0 | ${WANTED_INSTTYPE}
  SectionSetInstTypes "${SECTION_NAME}" $0
  Pop $0

!macroend

!macro ClearSectionInInstType SECTION_NAME WANTED_INSTTYPE

  Push $0
  Push $1
  SectionGetInstTypes "${SECTION_NAME}" $0
  StrCpy $1 ${WANTED_INSTTYPE}
  IntOp $1 $1 ~
  IntOp $0 $0 & $1
  SectionSetInstTypes "${SECTION_NAME}" $0
  Pop $1
  Pop $0

!macroend

위 두 매크로는 원하는 인스톨 타입에 섹션을 넣어줍니다. 즉, SectionIn 명령과 같다고 할 수 있습니다.
그 명령과 이 매크로의 차이점은 그 함수는 컴파일때 한번 정해지면 끝이지만 이 매크로는 실행되는 도중에 섹션의
포함관게등을 변경할 수 있습니다. WANTED_INSTTYPE에는 위에 정의된 INSTTYPE_1 등과 같은 값을 넣으면 됩니다.

;--------------------------------

; Set / clear / check bits in a section's flags
; Written by derekrprice

; Set one or more bits in a sections's flags

!macro SetSectionFlag SECTION BITS

  Push $R0
  SectionGetFlags "${SECTION}" $R0
  IntOp $R0 $R0 | "${BITS}"
  SectionSetFlags "${SECTION}" $R0
  Pop $R0

!macroend

; Clear one or more bits in section's flags

!macro ClearSectionFlag SECTION BITS

  Push $R0
  Push $R1
  SectionGetFlags "${SECTION}" $R0
  IntOp $R1 "${BITS}" ~
  IntOp $R0 $R0 & $R1
  SectionSetFlags "${SECTION}" $R0
  Pop $R1
  Pop $R0

!macroend

위의 두 매크로는 섹션의 비트 설정을 설정하거나 지웁니다.

; Check if one or more bits in section's flags are set
; If they are, jump to JUMPIFSET
; If not, jump to JUMPIFNOTSET

!macro SectionFlagIsSet SECTION BITS JUMPIFSET JUMPIFNOTSET
Push $R0
SectionGetFlags "${SECTION}" $R0
IntOp $R0 $R0 & "${BITS}"
IntCmp $R0 "${BITS}" +3
Pop $R0
StrCmp "" "${JUMPIFNOTSET}" +3 "${JUMPIFNOTSET}"
Pop $R0
Goto "${JUMPIFSET}"
!macroend

위 매크로는 지정한 섹션에서 지정한 플래그들이 설정되어 있는지 조사합니다. 그리고 같으면 JUMPIFSET 으로 같지 않으면 JUMPIFNOTSET 으로 이동합니다.
JUMPIFSET과 JUMPIFNOTSET에는 숫자값을 이용한 절대 주소이동방법을 사용하면 매크로로 인한 주소값에 혼돈이 생겨 제대로 작동되지 않습니다. 물론, 이미
매크로의 주소값까지 계산해서 넣으면 상관없습니다만... 라벨을 만들어서 사용할 것을 적극 권장합니다.

;--------------------------------

!endif

파일 맨 위에 있던 SECTIONS_INCLUDE값에 따라 내용이 포함될 지 여부를 가릅니다.
if문으로 설정되어 있어 한번이라도 포함되면 인스톨러에 SECTIONS_INCLUDE라는 상수가 생성됩니다.
그러면 그담에 다시 포함시킬때 이 상수를 보고 포함시키지 않습니다.

!ifndef SECTIONS_INCLUDED
!define SECTIONS_INCLUDED

댓글을 달아 주세요