AIXLOGIS 로고AIXLOGIS
개발 일지

(Python_backup tool) PyInstaller로 패키징한 데스크톱 앱, 재실행하면 설정이 초기화되는 문제 해결기

#Python#PyInstaller#데스크톱앱#버그수정

개요

사내에서 사용하는 파일 동기화용 데스크톱 유틸리티를 exe 파일로 패키징해서 배포했는데, 정상적으로 동작하던 설정 저장 기능이 exe 실행 환경에서만 매번 초기화되는 현상이 발생했습니다. .py 스크립트로 직접 실행할 때는 문제가 없었기 때문에 원인 파악에 다소 시간이 걸렸던 케이스를 공유합니다.

문제 상황

  • 프로그램 실행 후 서버 접속 정보 등을 설정하고 저장
  • 프로그램을 종료했다가 다시 실행하면 저장했던 설정이 모두 사라져 있음
  • 개발 환경(python main.py)에서는 재현되지 않고, PyInstaller로 빌드한 .exe에서만 발생

원인 분석

PyInstaller의 --onefile 옵션으로 빌드하면, 실행 시점에 실행 파일 내부의 리소스를 OS 임시 폴더(예: %TEMP% 하위의 임시 디렉터리)에 압축 해제한 뒤 그 위치에서 코드를 구동합니다.

문제는 설정 파일의 저장 경로를 "현재 실행 중인 코드 파일이 위치한 폴더"를 기준으로 계산하고 있었다는 점이었습니다. 일반 스크립트 실행에서는 이 방식이 소스 코드가 있는 폴더를 정확히 가리키지만, --onefile로 번들된 exe에서는 매 실행마다 새로 생성되는 임시 폴더를 가리키게 됩니다. 그리고 이 임시 폴더는 프로세스가 종료되면 함께 삭제되므로, 그 안에 저장한 설정 파일도 다음 실행 때는 존재하지 않는 상태가 되는 것이었습니다.

해결 방법

핵심은 "코드가 번들된 실행 파일 안에서 돌아가고 있는지"를 런타임에 판별해서, 기준 경로를 다르게 잡는 것이었습니다.

프로그램 시작 시:
  만약 (PyInstaller 번들 실행 환경으로 판별됨):
      기준_경로 = 실행 파일(.exe) 자체가 위치한 폴더
  아니면:
      기준_경로 = 현재 소스 파일이 위치한 폴더

  설정_파일_경로 = 기준_경로 + "config.json"
  로그_파일_경로 = 기준_경로 + "app.log"

번들 여부는 파이썬 런타임이 노출하는 표준 플래그로 판별할 수 있어서, 별도의 외부 의존성 추가 없이 분기 처리가 가능했습니다.

회고

  • 로컬 스크립트 실행과 패키징된 실행 파일은 "동일한 코드"라도 파일 시스템 관점에서 전혀 다른 환경일 수 있다는 점을 다시 확인했습니다.
  • 이후로는 경로 관련 로직을 작성할 때 "이 경로 계산이 배포 형태(스크립트/번들 exe)에 따라 달라질 수 있는가"를 항상 먼저 점검하는 습관을 들이게 되었습니다.
  • 배포 전 체크리스트에 "빌드된 실행 파일을 재실행해서 설정 유지 여부 확인"을 정식 항목으로 추가했습니다.
#Python#PyInstaller#데스크톱앱#버그수정

이슈와 관련된 다른 인사이트

DEV
개발 일지

(Python_backup tool) 종료 버튼을 눌렀는데 앱이 멈춘 것처럼 보이는 문제 해결하기

DEV
개발 일지

(Python_backup tool)파일 탐색기에 안전장치 더하기 — 충돌 감지와 휴지통 방식 삭제

DEV
개발 일지

(Python_backup tool) 백업 툴에 '다운로드' 기능을 추가하며 배운 방향 독립적 설계