Programming/Code Story

NSIS를 이용한 압축 파일 배포(NSIS 7Z PLUGIN)

Yuno.org 2010. 3. 27. 02:27
반응형

예전에 NSIS를 이용 할 경우 대용량 파일을 배포 할때 오류가 나는 문제에 대해서 포스팅을 한 적이 있다. (자세한 내용은 http://www.yuno.org/295 을 참고)

이 때, 해결 했던 방법 중에서 일반적으로 쓰인 방법이 인스톨러와 데이터 파일을 배포해서 2개 이상의 파일을 이용한 배포였다. 그런데, NSIS 자체에서 압축 기능을 지원하고는 있지만, 별도의 압축 파일을 처리 하는 모듈은 없기 때문에 NSIS의 EXCUTE SCRIPT 를 이용해서 COMMAND로 실행 가능한 7Z 압축 바이너리에 압축 풀 파일을 넘겨주어 압축을 푸는 방식을 이용했다.

즉, INSTALL.EXE 와 DATA.7Z 이렇게 2개의 파일을 배포 하지만 INSTALL.EXE 는 설치 능력은 있지만 DATA.7Z 파일의 압축을 풀 능력이 없기 때문에 INSTALL.EXE 자체에 7Z.EXE 를 함께 넣어서 설치 과정중에 7Z.EXE를 별도의 프로세스로 실행해서 DATA.7Z 를 압축 푸는 방식을 이용했다.

하지만, 이 방식이 조금 문제가 있는 것이.. 표준 스트림 버퍼를 이용을 하고는 있지만 7Z.EXE 에서 출력 되는 메세지가 이유를 알 수 없게 버퍼링이 되어서 현재 상태를 바로 보여 줄 수 없다는 문제가 있다. 다시 말하면, 100개의 파일을 압축 푸는데, 어떤 파일을 압축을 풀었다 라고 100번의 메세지가 DETAIL LOG에 나와야 하지만 어떠한 이유에서 이 출력될 LOG가 버퍼링 되어서 뭉쳐서 나오는 문제가 생긴 것이다.

따라서 설치 시간이 오래 걸리는 대용량 설치의 경우 유저들은 이게 설치가 되는건가? 하는 의구심을 품게 된다. 또한 현재 설치가 어느 정도 진행 됐는지 알 수가 없어서 답답함을 가질 수 밖에 없었다.

우리 회사에서도 NSIS를 이용한 배포를 하는데 항상 저 문제가 마음에 걸렸다. 언젠가 시간이 나면 NSIS용 7Z PLUG-IN을 만들어야겠다! 라고 생각하고 있었는데, 최근에 제작 할 시간이 생겨서 작업을 시작하고 보니.. 이런! 이미 나와있다. -_-

Nsis7z plug-in ( 참고 : http://nsis.sourceforge.net/Nsis7z_plug-in ) 을 이용할 경우 NSIS 인스톨러를 이용해서 압축을 풀 수 있게 된다. 대용량 파일을 압축 풀더라도 버퍼링으로 인한 메세지가 밀려서 나오는 문제도 해결 할 수 있을 뿐만 아니라, 현재 설치 상태를 % 로도 표시를 할 수 있다.

사용법도 매우 간단해서, 기존의 처럼 7Z.EXE 를 더 이상 인스톨러에 포함하지 않아도 된다. 플러그인을 다운 받아서 NSIS7Z.DLL 파일은 NSIS의 PLUGIN 폴더에 넣어주면 준비 끝. 그 다음에는 인스톨 스크립트에 몇줄만 추가 하면 완료다.

이 플러그인을 이용 할 경우 2가지 배포 방법을 이용 할 수 있다.

NSIS는 인스톨러 컴파일을 할때 설치 데이터를 인스톨러에 함께 묶는데, 1) 이때 데이터 파일을 함께 묶는 방법, 그리고 2) 데이터 파일을 인스톨러와 별도로 배포 하는 방법으로 나뉘어 진다

1)의 경우는 작은 용량의 배포에 알맞다.
2)의 경우는 대용량 파일을 배포 할때 알맞다. NSIS가 단일 파일을 2GB 이상 지원 하지 않기 때문에 2GB 이상의 데이터를 배포 한다면 별개의 데이터 파일로 배포 하는 것이 좋다.

또한 비스타에서 실행 파일의 용량이 대용량일 경우 실행 시간이 매우 오래 걸리는 문제가 있는데, 이 문제 역시 별도의 데이터 파일을 이용 할 경우 해결 된다.


자, 그러면 플러그인에서 지원하는 명령어들을 확인해 보자. 이 플러그인은 총 3개의 명령어를 지원한다.

Nsis7z::Extract

제일 기본 적인 압축 해제 명령으로 Nsis7z::Extract "ArchiveName.7z" 와 같은 방식으로 사용을 한다. 압축이 풀리는 동안 인스톨러에 표시 되는 프로그레스바는 정상적으로 그 값을 표시 한다.

참고로, 인스톨러의 실행 위치에 함께 있는 파일을 압축 풀기 위해서는
Nsis7z::Extract "$EXEDIR\ArchiveName.7z" 로 경로를 함께 지정해주어야 한다.

경로를 반환하는 상수들에 대해서는 여기를 참고!

Nsis7z::ExtractWithDetails

기본 압축 해제 명령에 % 표시 기능을 추가 한 명령.
Nsis7z::ExtractWithDetails "DATA.7z" "Installing package %s..." 와 같이 2번째 파라미터에 스트링을 넘겨 주면 그에 알맞게 % 표시를 해준다. 위의 명령을 예로 들면 Installing package %s... 을 Installing package 퍼센트% ( 현재 용량 / 전체 용량 ) 으로 표시해준다.

Nsis7z::ExtractWithCallback

마지막으로 ExtractWithCallback의 경우 압축을 다 푼후 지정한 콜백 함수를 호출한다. 콜백을 호출 해줄 뿐 명령 자체는 Extract와 동일하다.

GetFunctionAddress $R9 CallbackFunction  ; CallbackFunction의 호출 주소를 $R9에 저장
Nsis7z::ExtractWithCallback "Data.7z" $R9 ; Data.7z의 압축 해제 후 $R9 주소 함수 호출


위의 3개 함수를 이용하면 각 현재 진행 상태를 안정적으로 표시 할 수 있다. 다만, 이 플러그인의 조금 아쉬운 점은 압축 풀고 있는 파일명을 표시 안해주는 것이다. 하지만, 이 플러그인은 코드가 공개 되어 있으므로 조금만 수정하면 현재 압축 해제 파일명을 DetailPrint 를 이용하여 표시하는 것은 큰 문제가 되지 않을 것이라 생각된다.
반응형