From c08b2c1e5420493655c373e1c66e5210df6986c0 Mon Sep 17 00:00:00 2001 From: haosicheng Date: Mon, 29 Sep 2025 16:08:16 +0800 Subject: [PATCH] =?UTF-8?q?Todo:=20=E8=A1=A5=E5=85=85nsis=E9=9B=86?= =?UTF-8?q?=E6=88=90=E9=9C=80=E8=A6=81=E7=9A=84=E4=BE=9D=E8=B5=96=20?= =?UTF-8?q?=E5=B9=B6=E6=8F=90=E4=BA=A4uninstall=20logo=E7=9A=84=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E8=B5=84=E6=BA=90=20=E5=B9=B6=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 12 +++---- installer/build_installer.py | 62 ++++++++++++++++++++++++------------ quick_build.py | 1 + 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/config.py b/config.py index 6a88fb5..2d9e57d 100644 --- a/config.py +++ b/config.py @@ -9,13 +9,13 @@ import json # 用于将令牌保存为 JSON 格式 # 后端服务器配置 # BACKEND_HOST = "192.168.5.233" -# BACKEND_HOST = "192.168.5.12" -BACKEND_HOST = "shuidrop.com" +BACKEND_HOST = "192.168.5.12" +# BACKEND_HOST = "shuidrop.com" # BACKEND_HOST = "test.shuidrop.com" -# BACKEND_PORT = "8000" -BACKEND_PORT = "" -# BACKEND_WS_URL = f"ws://{BACKEND_HOST}:{BACKEND_PORT}" -BACKEND_WS_URL = f"wss://{BACKEND_HOST}" +BACKEND_PORT = "8000" +# BACKEND_PORT = "" +BACKEND_WS_URL = f"ws://{BACKEND_HOST}:{BACKEND_PORT}" +# BACKEND_WS_URL = f"wss://{BACKEND_HOST}" # WebSocket配置 WS_CONNECT_TIMEOUT = 16.0 diff --git a/installer/build_installer.py b/installer/build_installer.py index 0258431..29ffda8 100644 --- a/installer/build_installer.py +++ b/installer/build_installer.py @@ -67,42 +67,61 @@ class NSISInstaller: # 创建assets目录 self.assets_dir.mkdir(exist_ok=True) - # 复制图标文件 + # 准备主程序图标 icon_sources = [ self.project_root / "static" / "ai_assistant_icon_64.png", self.project_root / "static" / "ai_assistant_icon_32.png", self.project_root / "static" / "ai_assistant_icon_16.png" ] - # 寻找可用的图标文件 + # 准备卸载程序专用图标 + uninstall_icon_source = self.project_root / "static" / "ai_assistant_icon_uninstall.png" + + # 转换主程序图标 icon_found = False for icon_source in icon_sources: if icon_source.exists(): - # 如果有PNG图标,我们需要转换为ICO格式 - # 这里暂时复制PNG,实际项目中建议准备ICO格式图标 - icon_dest = self.assets_dir / "icon.ico" try: - # 尝试使用PIL转换PNG为ICO格式 from PIL import Image img = Image.open(icon_source) ico_path = self.assets_dir / "icon.ico" img.save(ico_path, format='ICO', sizes=[(16,16), (32,32), (48,48), (64,64)]) - print(f"✅ 转换图标: {icon_source.name} -> icon.ico") + print(f"✅ 转换主程序图标: {icon_source.name} -> icon.ico") icon_found = True break except ImportError: print("⚠️ 未安装PIL库,跳过图标转换") break except Exception as e: - print(f"⚠️ 图标转换失败: {e}") + print(f"⚠️ 主程序图标转换失败: {e}") continue - if not icon_found: - print("⚠️ 未找到图标文件,将使用默认图标") + # 转换卸载程序图标 + uninstall_icon_found = False + if uninstall_icon_source.exists(): + try: + from PIL import Image + img = Image.open(uninstall_icon_source) + uninstall_ico_path = self.assets_dir / "uninstall_icon.ico" + img.save(uninstall_ico_path, format='ICO', sizes=[(16,16), (32,32), (48,48), (64,64)]) + print(f"✅ 转换卸载程序图标: {uninstall_icon_source.name} -> uninstall_icon.ico") + uninstall_icon_found = True + except ImportError: + print("⚠️ 未安装PIL库,跳过卸载图标转换") + except Exception as e: + print(f"⚠️ 卸载程序图标转换失败: {e}") + else: + print("⚠️ 未找到卸载程序专用图标,将使用主程序图标") - return icon_found + if not icon_found: + print("⚠️ 未找到主程序图标文件,将使用默认图标") + + return { + 'main_icon': icon_found, + 'uninstall_icon': uninstall_icon_found + } - def generate_nsis_script(self, has_icon=False): + def generate_nsis_script(self, icon_info): """生成NSIS安装脚本""" print("📝 生成NSIS安装脚本...") @@ -131,8 +150,8 @@ InstallDirRegKey HKLM "Software\\${{APP_PUBLISHER}}\\${{APP_NAME_EN}}" "InstallP # 界面设置 !include "MUI2.nsh" !define MUI_ABORTWARNING -{f'!define MUI_ICON "assets\\\\icon.ico"' if has_icon else ''} -{f'!define MUI_UNICON "assets\\\\icon.ico"' if has_icon else ''} +{f'!define MUI_ICON "assets\\\\icon.ico"' if icon_info.get('main_icon', False) else ''} +{f'!define MUI_UNICON "assets\\\\uninstall_icon.ico"' if icon_info.get('uninstall_icon', False) else f'!define MUI_UNICON "assets\\\\icon.ico"' if icon_info.get('main_icon', False) else ''} # 页面配置 !insertmacro MUI_PAGE_WELCOME @@ -168,16 +187,17 @@ Section "MainSection" SEC01 # 复制所有文件 File /r "..\\dist\\MultiPlatformGUI\\*.*" - # 复制图标文件到安装目录(如果有的话) - {f'File "assets\\\\icon.ico"' if has_icon else ''} + # 复制图标文件到安装目录 + {f'File "assets\\\\icon.ico"' if icon_info.get('main_icon', False) else ''} + {f'File "assets\\\\uninstall_icon.ico"' if icon_info.get('uninstall_icon', False) else ''} # 创建开始菜单快捷方式 CreateDirectory "$SMPROGRAMS\\${{APP_NAME}}" - {f'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}" "" "$INSTDIR\\\\icon.ico" 0' if has_icon else 'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}"'} - {f'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\卸载${{APP_NAME}}.lnk" "$INSTDIR\\\\uninstall.exe" "" "$INSTDIR\\\\icon.ico" 0' if has_icon else 'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\卸载${{APP_NAME}}.lnk" "$INSTDIR\\\\uninstall.exe"'} + {f'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}" "" "$INSTDIR\\\\icon.ico" 0' if icon_info.get('main_icon', False) else 'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}"'} + {f'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\卸载${{APP_NAME}}.lnk" "$INSTDIR\\\\uninstall.exe" "" "$INSTDIR\\\\uninstall_icon.ico" 0' if icon_info.get('uninstall_icon', False) else f'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\卸载${{APP_NAME}}.lnk" "$INSTDIR\\\\uninstall.exe" "" "$INSTDIR\\\\icon.ico" 0' if icon_info.get('main_icon', False) else 'CreateShortCut "$SMPROGRAMS\\\\${{APP_NAME}}\\\\卸载${{APP_NAME}}.lnk" "$INSTDIR\\\\uninstall.exe"'} # 创建桌面快捷方式 - {f'CreateShortCut "$DESKTOP\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}" "" "$INSTDIR\\\\icon.ico" 0' if has_icon else 'CreateShortCut "$DESKTOP\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}"'} + {f'CreateShortCut "$DESKTOP\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}" "" "$INSTDIR\\\\icon.ico" 0' if icon_info.get('main_icon', False) else 'CreateShortCut "$DESKTOP\\\\${{APP_NAME}}.lnk" "$INSTDIR\\\\${{APP_EXE}}"'} # 写入注册表 WriteRegStr HKLM "Software\\${{APP_PUBLISHER}}\\${{APP_NAME_EN}}" "InstallPath" "$INSTDIR" @@ -282,13 +302,13 @@ SectionEnd return False # 2. 准备资源文件 - has_icon = self.prepare_assets() + icon_info = self.prepare_assets() # 3. 创建许可证文件 self.create_license_file() # 4. 生成NSIS脚本 - installer_name = self.generate_nsis_script(has_icon) + installer_name = self.generate_nsis_script(icon_info) # 5. 构建安装包 if not self.build_installer(): diff --git a/quick_build.py b/quick_build.py index 21ff5a4..d3bf358 100644 --- a/quick_build.py +++ b/quick_build.py @@ -56,6 +56,7 @@ def build_with_command(): '--name=main', '--onedir', # 相当于 --exclude-binaries '--windowed', # 相当于 -w + '--icon=static/ai_assistant_icon_64.png', # 添加主程序图标 '--add-data=config.py;.', '--add-data=exe_file_logger.py;.', '--add-data=windows_taskbar_fix.py;.',