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:
claudi 2026-02-20 08:24:44 +01:00
parent a8aa54fa5e
commit bf7c7b5e5f
5 changed files with 2932 additions and 2874 deletions

View file

@ -1220,6 +1220,14 @@ Phase 4 Complete - Professional Features & Auto-Update system fully implemented
- ✅ Phase 4.3: Advanced Configuration & Settings UI (43 tests)
- ✅ 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:**
- Version: 1.0.0 (released Jan 28, 2026)
- 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

View file

@ -145,6 +145,9 @@ class WindowsBuilder:
if total_size > 0:
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
self.generate_checksum(exe_path)
@ -169,6 +172,52 @@ class WindowsBuilder:
print(f" File: {checksum_file}")
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:
"""Create MSI installer using WiX Toolset.

View file

@ -14,6 +14,7 @@ isort>=5.12.0
# Building
pyinstaller>=6.0.0
pefile>=2023.2.7
# Documentation
sphinx>=7.0.0