window 프로그램 펌웨어 업데이트를 할 경우 .bat 파일로 파일 스위칭 하는 것과 Microsoft Installer(.msi) 를 활용해서 파일을 바꾸는 것 중 어떤 것이 적절할지에 대한 고민
우리는 어떠한 파일을 설치함에 있어서 zip 파일을 bat 폴더와 함께 실행시켜 필요한 build 를 하고 원하는 파일을 원하는 디렉토리에 설치하는 방식을 사용하였다.
그런데 이 펌웨어가 가동되는 도중에 이 업데이트를 진행해야 하는 문제에 봉착하였다.
문제점은 다음과 같았다.
- admin 계정이 아닌 kiosk 계정으로 로컬디스크에 접근할 권한을 가질 수 있는가?
- 이미 프로세스에 의해 점유된 파일을 read/write 할 수 있겠는가?
1번 문제는 admin 계정으로 window scheduler를 등록함으로 인해 극복이 가능했다. 실행 주체가 굳이 kiosk 가 아니어도 상관이 없기 때문이었다.
2번 문제는 끝까지 문제를 일으켰다. 실행되고 있는 프로세스의 이름을 바꿔서 접근을 하려는 등 여러 시도를 했지만 깔끔한 해결책이 되지 못하였다.
따라서 윈도우가 제시하는 Microsoft Installer 를 만드는 파일인 프로그램인 wix를 사용했고, 그 안에서 버전정보를 입력하는 Minor upgrade 방식을 사용하여 해결을 했다.
wix, msi minor major update 는 다음 글을 보면 좋다.
window에서 업데이트 메시지 팝업을 띄울 시 어떤 함수를 사용할지에 대한 고민
Kiosk 프로세스가 돌아가는 환경에서 이 펌웨어를 업데이트 하겠냐고 물어보는 팝업을 띄워야 하는 상황이었습니다. 그런데 default shell 이 cmd.exe 로 설정이 되어 있었기에 최상단에 계속 .exe 가 띄워져 있는 상황이라서 팝업 메시지가 가려지는 에러가 발생을 하였습니다
초기에는 qt 로 다음과 같이 팝업을 띄웠었습니다
class MainDlg(QDialog):
def __init__(self):
super().__init__(windowTitle = 'xxxxx')
self.resize(200, 75)
self.setAttribute(Qt.WA_DeleteOnClose, True)
vbox = QVBoxLayout(self)
hbox = QHBoxLayout()
....
def run_msi():
main_dlg = MainDlg()
main_dlg.exec()
그러다가 더 권한이 강력한 win32api 로 만든 win32gui 에서 만든 팝업은 다른 윈도우 화면을 내리는 등 간섭을 할 수 있고, 심지어 화면의 최상단에 강제성을 갖고 띄울수 있다는 사실을 알게 되었기에 다음과 같이 리팩토링 하며 문제를 해결할 수 있었습니다.
거절 시 cmd.exe 창이 뜨는 문제까지도 win32gui 를 사용해서 해결할 수 있었습니다
def run_msi():
global is_firmware_updated
hwndMain = win32gui.FindWindow("Chrome_WidgetWin_1", None)
hwndCmd = win32gui.FindWindow("ConsoleWindowClass", None)
command = fr'msiexec /i {UPDATE_AUTHORIZER_PATH} REINSTALLMODE=vomus REINSTALL=ALL'
win32gui.ShowWindow(hwndMain, win32con.SW_HIDE)
result = win32ui.MessageBox(t('msi_update.message'), t('msi_update.title'), win32con.MB_YESNO)
if result == win32con.IDYES:
with lock_on_update_authorizer:
win32api.ShellExecute(0, "runas", "cmd.exe", f"/c {command}", None, 1)
elif result == win32con.IDNO:
win32gui.ShowWindow(hwndCmd, win32con.SW_HIDE)
win32gui.ShowWindow(hwndMain, win32con.SW_SHOW)
'개발' 카테고리의 다른 글
[wix] flask 프로젝트 윈도우 패키징 (1) | 2024.09.13 |
---|---|
[Flask] Frontend 템플릿 Jinja 구조 (0) | 2024.07.25 |
[Flask] flask backend 템플릿 구조 (0) | 2024.07.24 |
[WIX] Major upgrade, Minor upgrade 조건과 차이 (2) | 2024.07.24 |
[개발] Lock 과 동시성(python) (0) | 2023.09.18 |