본문 바로가기
코딩취미/프로그램 지식

NSIS 고급 활용 시리즈 ⑤ – 설치 복구 및 재설치 제어: Repair 모드 구현과 중복 방지

by 브링블링 2025. 6. 8.
반응형

NSIS 고급 활용 시리즈 ⑤ – 설치 복구 및 재설치 제어: Repair 모드 구현과 중복 방지

많은 상용 소프트웨어는 이미 설치된 프로그램이 감지되면 "복구(Repair)" 또는 "제거(Remove)" 옵션을 제공합니다.
NSIS로도 이런 기능을 구현할 수 있으며, 레지스트리 키, 존재하는 설치 경로, 사용자 선택값 등을 활용하여 구현할 수 있습니다.


✅ 주요 기능 요약

기능 설명
설치 여부 확인 레지스트리 또는 파일 유무로 설치 상태 감지
사용자에게 모드 선택 요청 CustomPage로 "Repair", "Remove", "Cancel" 선택 제공
선택에 따른 동작 분기 Repair: 재설치 / Remove: 언인스톨러 호출 / Cancel: 종료

🧠 ① 설치 여부 확인 – 레지스트리 감지

NSIS 설치 시 보통 다음과 같이 레지스트리 키를 등록합니다:

WriteRegStr HKLM "Software\MyCompany\MyApp" "InstallPath" "$INSTDIR"

 

설치기 실행 시, 이 값을 확인하여 기존 설치 여부를 판단할 수 있습니다.

Function .onInit
  ReadRegStr $0 HKLM "Software\MyCompany\MyApp" "InstallPath"
  StrCmp $0 "" no_previous_install

  ; 기존 설치 감지됨
  MessageBox MB_YESNO "이미 설치되어 있습니다. 복구하거나 제거하시겠습니까?" IDYES continue IDNO abort
  Goto continue

  no_previous_install:
    Return

  abort:
    Quit

  continue:
FunctionEnd

🧰 ② 사용자 선택 페이지 구성 – nsDialogs로 Repair 모드 구현

!include "nsDialogs.nsh"
Var CHOICE

Page custom ShowRepairPage HandleRepairPage

Function ShowRepairPage
  nsDialogs::Create 1018
  Pop $0

  ${NSD_CreateLabel} 0u 10u 100% 12u "설치된 프로그램이 이미 존재합니다. 아래에서 원하는 작업을 선택하세요."

  ${NSD_CreateRadioButton} 10u 30u 100% 12u "복구 설치 (Repair)"
  Pop $1
  ${NSD_CreateRadioButton} 10u 50u 100% 12u "프로그램 제거 (Remove)"
  Pop $2
  ${NSD_CreateRadioButton} 10u 70u 100% 12u "설치 중단 (Cancel)"
  Pop $3

  nsDialogs::Show
FunctionEnd

Function HandleRepairPage
  ${NSD_GetState} $1 $CHOICE
  ${If} $CHOICE = 1
    StrCpy $CHOICE "repair"
    Return
  ${EndIf}
  ${NSD_GetState} $2 $CHOICE
  ${If} $CHOICE = 1
    StrCpy $CHOICE "remove"
    Return
  ${EndIf}
  ${NSD_GetState} $3 $CHOICE
  ${If} $CHOICE = 1
    StrCpy $CHOICE "cancel"
    Quit
  ${EndIf}
FunctionEnd
반응형

🔄 ③ 선택에 따라 분기 처리

Section
  StrCmp $CHOICE "repair" 0 not_repair
    DetailPrint "Repair 모드로 진행 중"
    ; 기존 파일을 덮어씌우는 방식
    File /r "app\*.*"
    Goto end

  not_repair:
  StrCmp $CHOICE "remove" 0 end
    DetailPrint "Remove 모드로 언인스톨 실행"
    ExecWait '"$INSTDIR\uninstall.exe"'
    Quit

  end:
SectionEnd

🧪 추가: 자동 복구 트리거 예시 (파일 누락 시 복구)

Function .onInit
  IfFileExists "$INSTDIR\myapp.exe" file_exists
    MessageBox MB_OK "파일이 손상되었거나 삭제되었습니다. 복구를 시작합니다."
    StrCpy $CHOICE "repair"
  file_exists:
FunctionEnd

🛠️ 복구 시 기존 설정 유지

복구 시 사용자 설정이 담긴 파일(.ini, .cfg, 로그 등)은 삭제하지 않도록 예외 처리할 수 있습니다.

SetOverwrite on
File /r /x settings.ini /x logs\*.* "app\*.*"

🔍 설치 중복 방지 옵션

설치기를 중복 실행하지 못하도록 하려면 System::Call로 실행 중인 인스턴스를 감지하거나, FindWindow/mutex 등을 사용할 수 있습니다.

반응형