1. NSIS

1.1. Opening Statement

보통 프로그램을 개발하고 나서 '만들었다' 로 끝나는 경우가 많다. 하지만, 정작 배포때에는 할일이 많다. 특히 제어판 프로그램 등록/삭제 에 등록되는 방식이라던지, 레지스트리를 건드린다던지, Program Files 폴더에 복사한다던지. 이 경우에는 보통 전용 Installer 프로그램을 쓰게 되지만, 아직 제대로 써본 적이 없었던 것 같다.

이번에는 '배포' 라는 녀석에 대해 촛점을 맞춰보고자, 인스톨러중 하나인 NSIS 에 대해 간단히 정리하고자 한다. (자.. 이제 폼좀 내면서 만든 프로그램 보여주자. ^^; 이게 가장 큰 목적. --;)

nsis 는 free software 이며, 소스가 공개되어있다. 관심있는 사람들은 분석해보시길.

1.2. 참조 링크

1.3. 전체 과정

NSIS의 원리는 간단하다. nsi 라는 스크립트 화일을 해석해서 해당 맞는 프로그램들을 하나의 화일로 압축시키고 실행프로그램으로 만드는 것이다. (마치 배치화일을 작성한다고 생각할수도 있겠다.)

  1. 프로그램을 개발한다.
  2. NSI Script 를 작성한다.
  3. makensis 로 Script 를 컴파일한다. 그러면 makensis 는 스크립트를 분석하면서 포함해야 할 화일들을 하나로 묶어준다. 그리고 zip의 형식으로 압축해준다. (내부적으로 zip2exe 가 이용된다. 이건 zlib 사용됨.)
  4. 하나의 Install 화일 생성. 완료. (뿌리자~ -_-v)

1.4. MakeNSIS usage

NSIS installer들은 'MakeNSIS' 프로그램에 의해서 NSI script (.NSI) 를 컴파일함으로서 만들어진다.
makensis 의 실행 문법은 대강 다음과 같다.

~cpp 
Makensis [/Vx] [/Olog] [/LICENSE] [/PAUSE] [/NOCONFIG] [/CMDHELP [command]] [/HDRINFO] [/CD] [/Ddefine[=value] ...]
         ["/XCommand parameter" ...] [Script.nsi | - [...]]
  • /LICENSE - license page를 보여준다.
  • /Vx (x는 0~4) - output 의 표시 정도를 조절한다.
    0 : no output
    1 : errors only
    2 : warnings and errors
    3 : info, warnings, and errors
    4 : all output
  • /Olog (log 는 filename) - compile 중 screen 상에 해당 화일에 대한 log를 표시하는 대신 화일로 설정한다.
  • /PAUSE - Makensis 가 종료되기 전 중간에 일시정지해준다. 이는 Windows 에서 직접 실행할 때 유용하다.
  • /NOCONFIG - nsisconfi.nsi 을 포함하지 않는다. 이 파라메터가 없는 경우, 인스톨러는 기본적으로 nsisconf.nsi 로부터 기본설정이 세팅된다. (NSIS Configuration File 참조)
  • /CMDHELP - command 에 대한 기본적인 사용정보를 출력해준다.

하지만 거의 기본 옵션이상 잘 안쓰게 될 것이다. ^^;

1.5. 효율적인 개발작업환경

NSIS 는 인스톨하고 난 뒤에는 오른쪽버튼 shell-extension 에 해당 확장자 컴파일이 등록된다. 하지만 command 로 수동으로 옵션을 설정하면서 입력해주는 것이 더 편하다.

또는 Editplus 의 사용자도구그룹에 makensis 을 등록시켜서 사용하는 방법도 있겠다. (nsis 를 위한 간단한 ide 만들어서 써먹어보는중.. 이였지만. 엉엉.. 그래도 editplus 가 훨 편하긴 하다. --;)

1.6. .NSI script 기본 문법

NSIS Script File (.nsi) 는 command 들의 묶음인 batch-file와도 같아보이는 text file이다.
  • ; 나 # 으로 시작되는 행들은 전부 comment 이다.
  • ;, # 뒤에 나오는 것 또한 comment 로 취급된다.
  • 주석이 아닌 행들은 'command parameter' 의 형태를 띤다.
  • parameter 의 숫자들은 10진수, 16진수, 8진수들을 이용할 수 있다. (일반 숫자, 0x__, 0124 식으로..)
  • 표현하고자하는 string 에 공백이 있으면 따옴표를 이용한다.
    ex)

~cpp 
	MessageBox MB_OK "I'll be happy" ; this one puts a ' inside a string
	MessageBox MB_OK 'And he said to me "Hi there!"' ; this one puts a " inside a string
	MessageBox MB_OK `And he said to me "I'll be fucked!"` ; this one puts both ' and "s inside a string:
  • 하나의 command 가 여러줄을 이용하는 경우 '' 를 사용한다.

~cpp 
    CreateShortCut "$SMPROGRAMS\NSIS\ZIP2EXE project workspace.lnk" \
                   "$INSTDIR\source\zip2exe\zip2exe.dsw"
    MessageBox MB_YESNO|MB_ICONQUESTION \
               "Remove all files in your NSIS directory? (If you have anything \
you created that you want to keep, click No)" \
                IDNO NoRemoveLabel


1.7. NSI Script Study

NSIS 는 스크립트 기반으로 일종의 배치화일과 같으므로, 예제위주의 접근을 하면 쉽게 이용할 수 있다. NSIS/예제1, NSIS/예제2, NSIS/예제3 등을 분석하고 소스를 조금씩 용도에 맞게 수정하여 작성하면 쉽게 접근할 수 있을 것이다. 의문이 생기는 명령어나 속성(attribute)에 대해서는 NSIS/Reference 를 참조하기 바란다.

1.8. CHM Document

NSIS 의 windows installer 버전을 설치하면 NSIS.CHM 화일이 같이 있다.

1.9. NSIS 에서 인스톨 중 Explorer 창 전부 닫기

1.10. 해당 dll 들 system32 의 디렉토리에 복사해주기

~cpp 
;copy files
File /r `.\tmp\*.*`
;system32 에 복사해줄 dll 들도 일단 복사해준다.
File /r `.\AdditionalDLL\*.dll` 

;move system addtinoal dlls to system folder
Rename "$INSTDIR\MSVCP60.dll" "$SYSDIR\MSVCP60.dll"


1.11. windows 깔린 위치 찾아오기

이용 예 : windows 의 system32 디렉토리에 dll 들을 복사해줄 때.

~cpp 
Section "ThisNameIsIgnoredSoWhyBother?" 
  .
  .
  MessageBox MB_OK "$WINDIR"
  MessageBox MB_OK "$SYSDIR"
  ; 복사할 화일을 추가하기. 
SectionEnd ; section 완료 


1.12. ExecWait

exec 로 해당 프로세스를 실행할 때 해당 프로세스가 죽을 때 까지 wait.
regsvr32.exe 로 dll 을 unregister 한 다음에 전체 폴더를 삭제할 때, regsvr32.exe 는 Exec 가 아닌 ExecWait 로 실행해주어야 한다. (그렇지 않으면 해당 dll 이 unregister 되기 전에 dll 화일이 delete 되어 정상적인 uninstall 이 되지 않을 수도 있다.)

1.13. NSIS 에서 특정 Process 가 살아있는지 여부 확인

FindProc Plugin 을 설치한다.


사용 예 : exec 로 regsvr32.exe 호출시 비동기 호출이 되어 뒤의 delete 문이 실행된다. 이를 방지하기 위한 방법으로 다음과 같이 한다.

~cpp 
  Exec 'regsvr32.exe /u /s "$INSTDIR\COMDLL.dll"'
  waitloop:
    FindProcDLL::FindProc "regsvr32.exe"
    IntCmp $R0 0 waitdone
    Sleep 500
    Goto waitloop
  waitdone:

  Delete "$INSTDIR\*.*"
  RMDir /r "$INSTDIR"


1.14. NSIS 에서 ActiveX Component 등록하기

http://nsis.sourceforge.net/archive/viewpage.php?pageid=435
~cpp 
;Inside the -Post section
Exec 'regsvr32.exe /s "$INSTDIR\${NAME_OF_MY_DLL}"'

;And Inside the Uninstall Section 
Exec 'regsvr32.exe /s /u "$INSTDIR\${NAME_OF_MY_DLL}"'


1.15. NSIS 에서 uninstall.exe 만들기


할 일 : 1. 'Uninstall' Section 을 만든다. 2. WriteInstaller 를 이용해준다.

~cpp 
;--------------------------------    
;Uninstaller Section  
Section "Uninstall"
   
;Delete Files 
  RMDir /r "$INSTDIR\*.*"    
 
;Remove the installation directory
  RMDir "$INSTDIR"
  
;Delete Start Menu Shortcuts
  Delete "$DESKTOP\${MUI_PRODUCT}.lnk"
  Delete "$SMPROGRAMS\${MUI_PRODUCT}\*.*"
  RmDir  "$SMPROGRAMS\${MUI_PRODUCT}"
  
;Delete Uninstaller And Unistall Registry Entries
  DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${MUI_PRODUCT}"
  DeleteRegKey HKEY_LOCAL_MACHINE
"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}"  
  
SectionEnd

Section ""
.
.
.

;레지스트리에 uninstall 프로그램 셋팅해주는 부분
;write uninstall information to the registry
  WriteRegStr HKLM
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}"
"DisplayName" "${MUI_PRODUCT} (remove only)"
  WriteRegStr HKLM
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}"
"UninstallString" "$INSTDIR\Uninstall.exe"

; Uninstaller 를 만드는 부분 
WriteUninstaller "$INSTDIR\Uninstall.exe"

SectionEnd


2. Thread

--fnwinter 형 고마워여~ NSIS 쓰는거 정리 할 필요가 있었는 데 , PS 이거 말고도 INNO SETUP 이라는 프로그램이 있거든요. 그것도 괜찮은데, 한번 써보세요~
몇몇 유틸리티 인스톨러에서 InnoSetup 쓰는거 종종 보였었는데, 이것도 공짜였군..~ 그나저나, http://isfd.kaju74.de/index.php?screenshots . 너무 뽀대나는거 아냐?;; --1002
Retrieved from http://wiki.zeropage.org/wiki.php/NSIS
last modified 2021-02-07 05:23:50