간만의 포스팅(3년만...)


간만의 NSIS...


퀘스트는 제목과 같았다...

설치 중 취소하면 취소 전 설치 된 파일을 모두 삭제해 주세요.

고난의 시작이었다.


파일을 설치하기 전단계에서의 취소는 어차피 하드에 기록한게 없으니 상관 없다.


문제는 파일을 설치하는 도중에 취소를 할 경우...


파일 설치는 별도의 thread 에서 처리되고 있어서, 파일 설치 중 강제로 페이지를 이동시키거나 해도 파일 설치 thread 는 계속 동작한다.


그러니 main thread 에서 파일을 삭제해도 제대로 지워지지 않는다.


파일 설치 thread 를 제어할 방법이 있으려나해서 nsis 소스까지 까봤으나 없다. 왜!!


google 느님에게 물어보면 복잡스런 코드가 있기는 한데 이건 취소하면 변수 하나에 취소 했다고 체크해두고


파일 설치에서 한 아이템을 설치 할 때마다 해당 변수를 체크해서 중단하거나 한다.


요거 -> http://nsis.sourceforge.net/InstFiles_Cancel_-_Allowing_a_user_to_cancel_installation_during_InstFiles


하지만, 문제는 너무 번거롭기도 하거니와 설치 스크립트를 아래처럼 폴더로 지정한 경우는 사용이 불가하다. Orz...


    File /r ..\src\* # 이 경우 하나의 아이템으로 처리되고 있어 중단할 수 없다.


결국, 3 일간의 삽질 끝에 해결한 방법을 대충 정리하면 아래와 같다.

  • 설치 SECTION에서 가장 먼저 uninstall.exe 파일을 설치한다. ( 원래는 -post 에서 설치된다. )
  • !define MUI_CUSTOMFUNCTION_ABORT "onUserAbort" # 취소 처리를 제어할 수 있도록 등록한다.
  • 전역 변수 하나를 설정하여, 파일 설치 전 취소 처리에서 알 수 있도록 값을 지정해둔다.
  • onUserAbort 함수에서 파일 설치 중에 취소 했음이 확인 되면 uninstall.exe 를 silent 모드로 실행한다.
    예) ExecWait '"cmd.exe" /C start "" "$INSTDIR\uninstall.exe" /S'
  • uninstall.exe 호출시 주의할 점은 nsExec::Exec 를 이용하면 안된다. nsExec::Exec 를 이용하면 파일 손상 에러가 난다. (이유는 모름.)
  • un.onInit 에서 silent 모드인 경우 설치 프로세스를 종료하도록 처리 한다.

Function un.onInit

    ${GetParameters} $R0

    ${If} $R0 == "/S"

        nsExec::Exec 'taskkill /F /IM ${OutFile}'

        Sleep 2000

    ${EndIf}


상세 코드는 귀찮으니.... 나중에 생각나면 정리해서 올려야겠다.

반응형

+ Recent posts