Add executable versioning support for Windows builds
- Implemented `set_exe_version` method in `WindowsBuilder` to set the version information for the generated executable. - This ensures proper MSI updates by comparing file versions. - Added error handling for missing `pefile` dependency and version resource. - Updated `requirements-dev.txt` to include `pefile` as a dependency for building.
This commit is contained in:
parent
a8aa54fa5e
commit
bf7c7b5e5f
5 changed files with 2932 additions and 2874 deletions
|
|
@ -1220,6 +1220,14 @@ Phase 4 Complete - Professional Features & Auto-Update system fully implemented
|
||||||
- ✅ Phase 4.3: Advanced Configuration & Settings UI (43 tests)
|
- ✅ Phase 4.3: Advanced Configuration & Settings UI (43 tests)
|
||||||
- ✅ Total Phase 4: 139 tests passing, 90%+ coverage
|
- ✅ Total Phase 4: 139 tests passing, 90%+ coverage
|
||||||
|
|
||||||
|
**MSI Update Support (Feb 20, 2026):**
|
||||||
|
- ✅ Added `<MajorUpgrade />` element to WiX configuration (build/WebDropBridge.wxs)
|
||||||
|
- ✅ Configured `Schedule="afterInstallInitialize"` for safe upgrade flow
|
||||||
|
- ✅ Implemented EXE version information setting in build script (build/scripts/build_windows.py)
|
||||||
|
- ✅ Added pefile dependency for version injection
|
||||||
|
- Impact: MSI installer now properly detects and applies version updates
|
||||||
|
- Status: Ready for Phase 5 release candidate builds
|
||||||
|
|
||||||
**Application Status:**
|
**Application Status:**
|
||||||
- Version: 1.0.0 (released Jan 28, 2026)
|
- Version: 1.0.0 (released Jan 28, 2026)
|
||||||
- Phase 1-3: Complete (core features, testing, build system)
|
- Phase 1-3: Complete (core features, testing, build system)
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -145,6 +145,9 @@ class WindowsBuilder:
|
||||||
if total_size > 0:
|
if total_size > 0:
|
||||||
print(f" Total size: {total_size / 1024 / 1024:.1f} MB")
|
print(f" Total size: {total_size / 1024 / 1024:.1f} MB")
|
||||||
|
|
||||||
|
# Set executable version information (required for MSI updates)
|
||||||
|
self.set_exe_version(exe_path)
|
||||||
|
|
||||||
# Generate SHA256 checksum
|
# Generate SHA256 checksum
|
||||||
self.generate_checksum(exe_path)
|
self.generate_checksum(exe_path)
|
||||||
|
|
||||||
|
|
@ -169,6 +172,52 @@ class WindowsBuilder:
|
||||||
print(f" File: {checksum_file}")
|
print(f" File: {checksum_file}")
|
||||||
print(f" Hash: {checksum}")
|
print(f" Hash: {checksum}")
|
||||||
|
|
||||||
|
def set_exe_version(self, exe_path: Path) -> None:
|
||||||
|
"""Set executable file version for Windows.
|
||||||
|
|
||||||
|
This is important for MSI updates: Windows Installer compares file versions
|
||||||
|
to determine if files should be updated during a major upgrade.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
exe_path: Path to the executable file
|
||||||
|
"""
|
||||||
|
print("\n🏷️ Setting executable version information...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pefile
|
||||||
|
except ImportError:
|
||||||
|
print("⚠️ pefile not installed - skipping EXE version update")
|
||||||
|
print(" Note: Install with: pip install pefile")
|
||||||
|
print(" EXE version info will be blank (MSI updates may not work correctly)")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
pe = pefile.PE(str(exe_path))
|
||||||
|
|
||||||
|
# Parse version into 4-part format (Major, Minor, Build, Revision)
|
||||||
|
version_parts = self.version.split(".")
|
||||||
|
while len(version_parts) < 4:
|
||||||
|
version_parts.append("0")
|
||||||
|
|
||||||
|
file_version = tuple(int(v) for v in version_parts[:4])
|
||||||
|
|
||||||
|
# Set version resource if it exists
|
||||||
|
if hasattr(pe, "VS_FIXEDFILEINFO"):
|
||||||
|
pe.VS_FIXEDFILEINFO[0].FileVersionMS = (file_version[0] << 16) | file_version[1]
|
||||||
|
pe.VS_FIXEDFILEINFO[0].FileVersionLS = (file_version[2] << 16) | file_version[3]
|
||||||
|
pe.VS_FIXEDFILEINFO[0].ProductVersionMS = (file_version[0] << 16) | file_version[1]
|
||||||
|
pe.VS_FIXEDFILEINFO[0].ProductVersionLS = (file_version[2] << 16) | file_version[3]
|
||||||
|
|
||||||
|
# Write modified PE back to file
|
||||||
|
pe.write(filename=str(exe_path))
|
||||||
|
print(f"✅ Version set to {self.version}")
|
||||||
|
else:
|
||||||
|
print("⚠️ No version resource found in EXE")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Could not set EXE version: {e}")
|
||||||
|
print(" MSI updates may not work correctly without file version info")
|
||||||
|
|
||||||
def create_msi(self) -> bool:
|
def create_msi(self) -> bool:
|
||||||
"""Create MSI installer using WiX Toolset.
|
"""Create MSI installer using WiX Toolset.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ isort>=5.12.0
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
pyinstaller>=6.0.0
|
pyinstaller>=6.0.0
|
||||||
|
pefile>=2023.2.7
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
sphinx>=7.0.0
|
sphinx>=7.0.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue