logo

한국어
NSIS 에서 MUI 를 이용하여 사용자 페이지 추가하기
헬마입니다.

이번에 코덱팩에 몇 가지 사용자페이지들을 추가하면서 혹시 모르시는 분이 계실까봐 간단하게나마 글을 하나 써봅니다. 물론, 저의 형편없는 글솜씨로 더욱 모르시는분이 늘어나실지도 모르겠지만 ... ^^

  NSIS 는 기본적으로 몇 가지 종류의 정해진 화면을 제공합니다. 이러한 화면들은 설치관리자에서 거의 필수불가결로 쓰일만큼 필수적인 화면들이지요.  하지만, 언제나 이런 화면들만 이용해서 설치관리자를 만들 수는 없습니다. 우리들이 의도하는 모든 일을 처리할 수 있는것도 아니구요. 그래서 NSIS 는 이에 대한 대안으로 사용자가 직접 화면을 제작하여 나타내는 방법을 제공합니다. 지금부터 간단히 코덱팩에 쓰인 코드 일부분을 예제로 이용하여 사용자페이지를 하나 제작해보겠습니다.



1. 준비물 : Eclipse 나 HM Nis Edit 등 화면제작이 가능한 에디터 , 없어도 되지만 없으면 직접 위치 입력등을 계산해서 넣어줘야 하기때문에 매우 매우 귀찮아집니다 ㅠㅠ

  NSIS 의 사용자페이지는 특정한 문법을 갖춘 ini 파일이라고 할 수 있습니다.

  필수적으로 [Settings] 라는 섹션과 이 섹션에는 화면에 나타낼 컨트롤의 숫자를 나타내는 NumFields 라는 항목이 있어야 하며 여기에 적은 수 만큼 [Fields 1] [Fields 2] 이런식으로 섹션들이 이어집니다. NumFields 항목의 수와 [Fields #] 항목의 수는 반드시 일치해야합니다.
  [Fields #] 섹션에는 이 컨트롤의 종류를 나태는 Type 항목, 위치를 나타내는 Top,Left, Bottom, Right 항목, 화면에 나태낼 문자열등을 저장하는 Text(종류에 따라 다를 수 있습니다), 컨트롤의 상태를 저장하는 State 항목(필수 항목은 아닙니다) 등으로 구성되어 있습니다.

 자세한 사항은 InstallOptions 도움말을 참조하세요 ^^

 만들어보는 예제는 ffdshow 컴포넌트가 컴포넌트 페이지에서 선택되어 있다면 ffdshow 설정 페이지가 나타나도록 하는걸로 하겠습니다.

 일단 기본적인 사항으로 ffdshow 섹션이 있고 이 섹션에 섹션인덱스를 저장할 변수를 할당해놔야 합니다(그래야 나중에 컴포넌트 선택여부를 파악할 수 있습니다)

예)
Section 'ffdshow' SecFFDShow  ; SecFFDShow 가 섹션인덱스 변수입니다.
~~~
SectionEnd

  일단 제일 먼저 에디터를 이용하여 화면을 제작해야겠지요. 자신이 원하는 대로 HM Nis Edit 나 Eclipse 등을 이용하여 제작 후 ffdshow.ini 라는 파일로 저장하여 스크립트와 같은 위치에 놓습니다.

  화면 제작이 끝나면 이제 이 화면이 나타나는 기본적인 순서를 정해줘야 합니다. 여지껏 NSIS 스크립트를 작성하면서 페이지 순서다 하면 생각나시는 코드가 있을겁니다. 바로 Page 명령인데요. 이를 이용해서 기존에 작성했던 곳에 끼워넣으시면 됩니다. 예제에서는 ffdshow 등 컴포넌트를 선택한 후 ffdshow 선택여부에 따라 페이지를 보여주려고 하니 컴포넌트 페이지 다음에 추가하겠습니다.

예)
!insertmacro MUI_PAGE_COMPONENTS
Page custom ffdshow'' ' : ffdshow 초기 설정을 합니다'
!insertmacro MUI_PAGE_INSTFILES


  에디터에서 사용하는 대로 색상 넣으려는 벅차네요 ^^

  위와 같이 컴포넌트 선택페이지와 설치 페이지 사이에 제작한 페이지를 끼워넣습니다.

  custom 은 사용자 페이지를 사용하겠다는 뜻이고, ffdshow 는 이 페이지를 화면에 나타내야할 일이 생기면 호출될

함수 이름입니다. 후에 우리가 제작해야하며 실질적으로 이 함수에서 화면을 나타냅니다. 즉, 여기 순서에 있다고 무조

건 화면에 나타나는건 아닙니다. 여기에 끼워넣은건 단지 이 순서가 되면 함수를 호출해서 화면을 나타낼 기회를 부여

받는다고 생각하시면 될 것 같네요. 그다음 '' 는 원래 화면을 떠날 때, 즉 사용자가 다음 버튼을 누르면 호출될 함수 이

름을 적습니다. 없으면 위와 같이 '' 를 넣으면 됩니다. 예를 들어, 다음 버튼을 눌렀을 때 특정 조건을 검사하여 넘어가

지 못하게 하고 싶다거나 하면 함수를 만들고 '' 부분에 만든 함수 이름을 적어주시면 됩니다. 그다음은 딱 보면 감이

오듯이 제목표시줄에 나타낼 문자열입니다.

-
 자 이제, 화면 출력 순서도 정했으니 실질적으로 설치관리자에서 화면을 나타내야겠죠. 화면을 출력하는 과정은 두가

지입니다. 사실 엄밀히 말하면 NSIS 자체는 사용자 페이지를 나타내지 못합니다. InstallOptions 라는 플러그인을 이용

합니다. 그런데, 보통 페이지들은 아직 우리가 진짜 사용자 컴퓨터에 설치하려는 파일들이 설치되기 전입니다. 따라

서, 설치관리자가 실행되자마자 , 화면이 나타나기도 전에 InstallOptions 플러그인과 사용자페이지 ini 파일을 먼저 압

축을 풀어서 초기화를 해줘야합니다. 이일을 .onInit 라는 콜백함수에서 처리합니다. 이 함수는 설치관리자가 실행되면

그 어떠한 함수보다 먼저 실행됩니다.

예)

Function .onInit
 !insertmacro MUI_INSTALLOPTIONS_EXTRACT "ffdshow.ini" ; 사용자 페이지를 저장한 ffdshow.ini 파일을 읽어옵니다.
FunctionEnd


이런식으로 매크로를 이용하여 초기화하고 압축을 풀어줄 ini 파일 이름을 적어줍니다.

-
 이제 마지막 작업이 남았습니다. 실질적으로 화면을 나타내주는 함수를 작성해야합니다.

출력함수에서는 MUI_INSTALLOPTIONS_DISPLAY 라는 매크로를 사용하여 ini 파일이름을 입력하면 출력됩니다. 하

지만, 무턱대고 바로 이 매크로를 사용하면 우리의 의도(ffdshow 컴포넌트가 선택되면 출력) 에 어긋나게 선택되지 않

았어도 화면이 출력됩니다. 따라서 역시 다른 매크로나 함수를 이용하여 컴포넌트 선택여부를 판별해야합니다.

여기에는 LogicLib 라는 헤더파일을 이용하는 방법과 Sections 헤더에서 제공하는 SectionFlagIsSet 이라는 매크로를

이용하는 방법의 두 가지가 있습니다. 전자의 방법이 코드를 보기도 쉽고, 작성도 쉽기 때문에 이 방법을 사용하겠습니다.

LogicLib 를 사용하려면 LogicLib.nsh 를 포함시켜야합니다.

예)

Functionffdshow
 ${If} ${SectionIsSelected} ${SecFFDshow}
  !insertmacro MUI_INSTALLOPTIONS_DISPLAY
'ffdshow.ini'
${EndIf}
FunctionEnd


위와 같이 작성하시면 됩니다. ffdshow 는 아까 page 명령에서 지정한 함수이름입니다.

 ${If} ${EndIf} 명령은 LogicLib 헤더에서 제공하는 제어문입니다. 이를 이용하면 Goto 등을 이용하지 않고 코드를 좀

더 간결하고 알아보기 쉽게 작성할 수 있습니다. ${SectionIsSelected} 는 LogicLib 에서 제공하는 ${If} 에서 사용하

는 검사명령으로 섹션이 선택되어 있으면 아래 문장등을 실행합니다.  ${SecFFDShow} 는 위에서 제일 처음 언급한

ffdshow 섹션에 대한 섹션인덱스 입니다.


그럼 부족한 글솜씨로 간단하게 적어보았습니다