diff --git a/HarmonyDevTools_Python/README_Python.md b/HarmonyDevTools_Python/README_Python.md index b4a295a..fa9251f 100644 --- a/HarmonyDevTools_Python/README_Python.md +++ b/HarmonyDevTools_Python/README_Python.md @@ -65,9 +65,10 @@ python build.py 构建脚本会: - 自动检查PyInstaller是否安装 - 自动清理之前的构建文件 -- 构建HarmonyDevTools.exe +- 构建HarmonyDevTools_v版本号.exe(包含版本信息) - 自动创建完整的发布包 -- 生成启动脚本和说明文档 +- 生成说明文档 +- 构建完成后自动清理临时文件 ### 4.2 使用PyInstaller手动打包 @@ -76,10 +77,25 @@ python build.py pip install pyinstaller # 打包为exe文件 -pyinstaller --onefile --windowed --name HarmonyDevTools main.py +pyinstaller --onefile --windowed --name HarmonyDevTools_v版本号 main.py ``` -### 4.3 使用auto-py-to-exe(GUI工具) +### 4.3 版本管理 + +```bash +# 更新版本号 +python update_version.py + +# 查看当前版本 +# 运行 update_version.py 会显示当前版本 +``` + +**版本号格式**: x.y.z (例如: 1.4.0) +- 文件名格式: HarmonyDevTools_v1_4_0.exe +- 程序内显示: 1.4.0(构建时通过命令行参数传递) +- 版本号来源: version_info.txt(main.py中的VERSION变量用于开发调试) + +### 4.4 使用auto-py-to-exe(GUI工具) ```bash # 安装auto-py-to-exe @@ -94,6 +110,9 @@ auto-py-to-exe ``` HarmonyDevTools_Python/ ├── main.py # 主程序文件 +├── build.py # 构建脚本 +├── version_info.txt # 版本信息文件 +├── update_version.py # 版本更新脚本 ├── requirements.txt # Python依赖文件 ├── README_Python.md # 说明文档 ├── toolchains/ # 工具链目录 diff --git a/HarmonyDevTools_Python/build.py b/HarmonyDevTools_Python/build.py index 4aaea42..bbc32e9 100644 --- a/HarmonyDevTools_Python/build.py +++ b/HarmonyDevTools_Python/build.py @@ -9,6 +9,7 @@ import os import sys import subprocess import shutil +import re from pathlib import Path def check_pyinstaller(): @@ -30,6 +31,54 @@ def install_pyinstaller(): print("PyInstaller安装失败!") return False +def get_version_from_version_info(): + """从version_info.txt文件中获取版本号""" + if not os.path.exists("version_info.txt"): + return "1.0.0" + + try: + with open("version_info.txt", 'r', encoding='utf-8') as f: + content = f.read() + match = re.search(r"StringStruct\(u'FileVersion', u'([^']+)'\)", content) + if match: + return match.group(1) + except Exception as e: + print(f"读取version_info.txt版本信息失败: {e}") + + return "1.0.0" + +def build_with_version(main_file, exe_name, version): + """使用指定版本号构建exe文件""" + # 构建命令,通过命令行参数传递版本号 + cmd = [ + "pyinstaller", + "--onefile", # 打包为单个文件 + "--windowed", # 无控制台窗口 + f"--name={exe_name}", # 输出文件名 + "--icon=icon.ico", # 图标文件(如果存在) + "--version-file=version_info.txt", # 版本信息文件 + "--add-data=toolchains;toolchains", # 包含toolchains目录 + f"--args=--version={version}", # 传递版本号参数给main.py + main_file + ] + + # 如果图标文件不存在,移除图标参数 + if not os.path.exists("icon.ico"): + cmd = [arg for arg in cmd if not arg.startswith("--icon")] + + # 如果版本信息文件不存在,移除版本信息参数 + if not os.path.exists("version_info.txt"): + cmd = [arg for arg in cmd if not arg.startswith("--version-file")] + + return cmd + +def get_version_for_filename(version): + """将版本号转换为文件名格式(只取前三位)""" + parts = version.split('.') + if len(parts) >= 3: + return f"{parts[0]}.{parts[1]}.{parts[2]}" + return version + def build_exe(): """构建exe文件""" print("开始构建exe文件...") @@ -39,28 +88,19 @@ def build_exe(): print("错误:找不到main.py文件!") return False + # 从version_info.txt获取版本号 + version = get_version_from_version_info() + version_for_filename = get_version_for_filename(version) main_file = "main.py" - exe_name = "HarmonyDevTools" - print("构建HarmonyDevTools...") + exe_name = f"HarmonyDevTools_v{version_for_filename}" + print(f"构建HarmonyDevTools v{version}...") # 检查toolchains目录是否存在 if not os.path.exists("toolchains"): print("警告:找不到toolchains目录,请确保包含hdc.exe文件") # 构建命令 - cmd = [ - "pyinstaller", - "--onefile", # 打包为单个文件 - "--windowed", # 无控制台窗口 - f"--name={exe_name}", # 输出文件名 - "--icon=icon.ico", # 图标文件(如果存在) - "--add-data=toolchains;toolchains", # 包含toolchains目录 - main_file - ] - - # 如果图标文件不存在,移除图标参数 - if not os.path.exists("icon.ico"): - cmd = [arg for arg in cmd if not arg.startswith("--icon")] + cmd = build_with_version(main_file, exe_name, version_for_filename) try: subprocess.check_call(cmd) @@ -99,7 +139,12 @@ def create_distribution(exe_name="HarmonyDevTools"): def create_release_readme(dist_dir): """创建发布版README文件""" - readme_content = """# HarmonyDevTools + # 获取当前版本号 + version = get_version_from_version_info() + version_for_filename = get_version_for_filename(version) + version_underscore = version_for_filename.replace('.', '_') + + readme_content = f"""# HarmonyDevTools HarmonyOS/OpenHarmony开发工具,提供图形化界面操作HDC工具。 @@ -113,7 +158,7 @@ HarmonyOS/OpenHarmony开发工具,提供图形化界面操作HDC工具。 ## 使用方法 -1. **启动程序**: 双击 `HarmonyDevTools.exe` 启动程序 +1. **启动程序**: 双击 `HarmonyDevTools_v{version_underscore}.exe` 启动程序 2. **连接设备**: 点击"列举设备"查看可用设备,输入connect key后点击"连接设备" 3. **安装应用**: 选择hap文件,设置安装选项后点击"安装hap" 4. **导出文件**: 点击"导出照片"或"导出日志"从设备导出文件 @@ -138,6 +183,7 @@ HarmonyOS/OpenHarmony开发工具,提供图形化界面操作HDC工具。 --- 基于原C# WPF项目转换的Python Tkinter版本 +版本: {version} """ readme_path = os.path.join(dist_dir, "README.md") @@ -152,7 +198,7 @@ def clean_build_files(): print("清理构建文件...") # 清理所有构建相关的临时文件 - dirs_to_clean = ["build", "dist", "__pycache__"] + dirs_to_clean = ["build", "__pycache__"] files_to_clean = ["HarmonyDevTools.spec", "HarmonyDevTools_Enhanced.spec"] for dir_name in dirs_to_clean: @@ -167,6 +213,24 @@ def clean_build_files(): print("清理完成") +def clean_after_build(exe_name): + """构建完成后清理临时文件""" + print("清理构建临时文件...") + + # 清理build目录 + if os.path.exists("build"): + shutil.rmtree("build") + print("已删除build目录") + + # 清理spec文件 + spec_files = [f"{exe_name}.spec"] + for spec_file in spec_files: + if os.path.exists(spec_file): + os.remove(spec_file) + print(f"已删除文件:{spec_file}") + + print("构建后清理完成") + def main(): """主函数""" print("=" * 50) @@ -202,6 +266,9 @@ def main(): # 自动创建发布包 create_distribution(exe_name) + # 构建完成后清理临时文件 + clean_after_build(exe_name) + print("\n构建完成!") print(f"exe文件位置:dist/{exe_name}.exe") print("发布包位置:dist/目录") diff --git a/HarmonyDevTools_Python/main.py b/HarmonyDevTools_Python/main.py index dfd9026..c8920ac 100644 --- a/HarmonyDevTools_Python/main.py +++ b/HarmonyDevTools_Python/main.py @@ -15,9 +15,13 @@ import logging import json import ctypes import webbrowser +import re from pathlib import Path from typing import Optional, Dict, Any +# 版本信息 +VERSION = "1.4.0" + # --- UI 界面 --- # 启用 DPI 感知(避免高分屏模糊) try: @@ -47,6 +51,14 @@ def center_window(win, width, height): y = (screen_height - height) // 2 win.geometry(f"{width}x{height}+{x}+{y}") +def get_version(): + """获取版本号""" + import sys + # 检查是否有命令行参数传入版本号 + if len(sys.argv) > 1 and sys.argv[1].startswith('--version='): + return sys.argv[1].split('=', 1)[1] + return VERSION + class Config: """配置管理类""" @@ -596,9 +608,10 @@ class HarmonyDevTools: def show_about(self): """显示关于信息""" - about_text = """HarmonyDevTools - Python版本 + version = get_version() + about_text = f"""HarmonyDevTools - Python版本 -版本: 1.0.0 +版本: {version} 作者: Python版本转换 功能: HarmonyOS/OpenHarmony开发工具 diff --git a/HarmonyDevTools_Python/test_version.py b/HarmonyDevTools_Python/test_version.py new file mode 100644 index 0000000..08ede53 --- /dev/null +++ b/HarmonyDevTools_Python/test_version.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +测试版本号传递功能 +""" + +import sys + +# 模拟main.py中的get_version函数 +def get_version(): + """获取版本号""" + # 检查是否有命令行参数传入版本号 + if len(sys.argv) > 1 and sys.argv[1].startswith('--version='): + return sys.argv[1].split('=', 1)[1] + return "1.4.0" # 默认版本号 + +if __name__ == "__main__": + version = get_version() + print(f"当前版本: {version}") + print(f"命令行参数: {sys.argv}") + + # 测试不同情况 + print("\n测试用例:") + print("1. 无参数运行: python test_version.py") + print("2. 带版本号运行: python test_version.py --version=2.0.0") + print("3. 其他参数运行: python test_version.py --help") diff --git a/HarmonyDevTools_Python/update_version.py b/HarmonyDevTools_Python/update_version.py new file mode 100644 index 0000000..6c679ce --- /dev/null +++ b/HarmonyDevTools_Python/update_version.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +版本信息更新脚本 +用于快速更新版本号 +""" + +import re +import os + +def update_version_info(new_version): + """更新版本信息文件""" + version_file = "version_info.txt" + + if not os.path.exists(version_file): + print(f"错误:找不到 {version_file} 文件") + return False + + # 解析版本号 + version_parts = new_version.split('.') + if len(version_parts) < 3: + print("错误:版本号格式应为 x.y.z (例如: 1.4.0)") + return False + + try: + major, minor, patch = map(int, version_parts[:3]) + build = 0 # 第四位默认为0 + except ValueError: + print("错误:版本号必须为数字") + return False + + # 读取文件内容 + with open(version_file, 'r', encoding='utf-8') as f: + content = f.read() + + # 更新版本号 + content = re.sub(r'filevers=\(\d+, \d+, \d+, \d+\)', + f'filevers=({major}, {minor}, {patch}, {build})', content) + content = re.sub(r'prodvers=\(\d+, \d+, \d+, \d+\)', + f'prodvers=({major}, {minor}, {patch}, {build})', content) + content = re.sub(r"StringStruct\(u'FileVersion', u'[^']+'\)", + f"StringStruct(u'FileVersion', u'{new_version}')", content) + content = re.sub(r"StringStruct\(u'ProductVersion', u'[^']+'\)", + f"StringStruct(u'ProductVersion', u'{new_version}')", content) + + # 写回文件 + with open(version_file, 'w', encoding='utf-8') as f: + f.write(content) + + print(f"版本信息已更新为: {new_version}") + print(f"下次构建将生成: HarmonyDevTools_v{new_version.replace('.', '_')}.exe") + print("注意:构建时会通过命令行参数传递版本号,main.py中的VERSION变量保持不变") + return True + +def main(): + """主函数""" + print("=" * 50) + print("HarmonyDevTools 版本更新工具") + print("=" * 50) + + # 显示当前版本 + if os.path.exists("version_info.txt"): + with open("version_info.txt", 'r', encoding='utf-8') as f: + content = f.read() + match = re.search(r"StringStruct\(u'FileVersion', u'([^']+)'\)", content) + if match: + current_version = match.group(1) + print(f"当前版本: {current_version}") + + # 获取新版本号 + print("\n请输入新版本号 (格式: x.y.z,例如: 1.4.0)") + new_version = input("新版本号: ").strip() + + if not new_version: + print("未输入版本号,操作取消") + return + + # 更新版本信息 + if update_version_info(new_version): + print("\n版本更新完成!") + print("现在可以运行 python build.py 来构建新版本") + else: + print("\n版本更新失败!") + +if __name__ == "__main__": + main() diff --git a/HarmonyDevTools_Python/util/upx.exe b/HarmonyDevTools_Python/util/upx.exe new file mode 100644 index 0000000..931073d Binary files /dev/null and b/HarmonyDevTools_Python/util/upx.exe differ diff --git a/HarmonyDevTools_Python/version_info.txt b/HarmonyDevTools_Python/version_info.txt new file mode 100644 index 0000000..508522d --- /dev/null +++ b/HarmonyDevTools_Python/version_info.txt @@ -0,0 +1,43 @@ +# UTF-8 +# +# For more details about fixed file info 'ffi' see: +# http://msdn.microsoft.com/en-us/library/ms646997.aspx +VSVersionInfo( + ffi=FixedFileInfo( + # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) + # Set not needed items to zero 0. + filevers=(1, 4, 0, 0), + prodvers=(1, 4, 0, 0), + # Contains a bitmask that specifies the valid bits 'flags'r + mask=0x3f, + # Contains a bitmask that specifies the Boolean attributes of the file. + flags=0x0, + # The operating system for which this file was designed. + # 0x4 - NT and there is no need to change it. + OS=0x40004, + # The general type of file. + # 0x1 - the file is an application. + fileType=0x1, + # The function of the file. + # 0x0 - the function is not defined for this fileType + subtype=0x0, + # Creation date and time stamp. + date=(0, 0) + ), + kids=[ + StringFileInfo( + [ + StringTable( + u'040904B0', + [StringStruct(u'CompanyName', u'HarmonyDevTools'), + StringStruct(u'FileDescription', u'HarmonyOS/OpenHarmony开发工具'), + StringStruct(u'FileVersion', u'1.4.0'), + StringStruct(u'InternalName', u'HarmonyDevTools'), + StringStruct(u'LegalCopyright', u'Copyright (C) 2025 DevWiki'), + StringStruct(u'OriginalFilename', u'HarmonyDevTools.exe'), + StringStruct(u'ProductName', u'HarmonyDevTools'), + StringStruct(u'ProductVersion', u'1.4.0')]) + ]), + VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) + ] +)