Compare commits

...
2 Commits
Author SHA1 Message Date
luzadev c2599a72a1 v1.7.7: fix avvio Windows definitivo (rimuove Mark of the Web)
La causa root del "Failed to resolve Python.Runtime.Loader.Initialize"
era il Mark of the Web (Zone.Identifier ADS) che Windows aggiunge ai
file estratti da uno zip scaricato dal browser. .NET Framework
rifiuta SILENZIOSAMENTE di risolvere i symbol export degli assembly
managed con MOTW.

Fix multilivello:
- main.py: al primo avvio cancella :Zone.Identifier da ogni
  .dll/.exe/.pyd nel bundle (via ctypes kernel32.DeleteFileW)
- CI: Unblock-File su dist/ pre-zip
- requirements: pythonnet==3.0.5 + clr-loader==0.2.7.post0 pinnati

Vedi: https://github.com/r0x0r/pywebview/issues/1215
      https://github.com/pyinstaller/pyinstaller/issues/7412
2026-06-09 12:37:48 +02:00
luzadev 2cc6c5e9c6 v1.7.6: secondo tentativo fix avvio Windows pythonnet
Preload esplicito di pythonnet.load("netfx") in main.py PRIMA di
importare webview: il lazy-import del 'clr' fallisce sotto PyInstaller
perche' Python.Runtime.dll viene bundlata ma il loader netfx non sa
risolverla.

Aggiunti:
- main.py: bootstrap pythonnet con PYTHONNET_RUNTIME=netfx + load()
- build_windows.py: --clean rebuild, --collect-data pythonnet/clr_loader
  (per Python.Runtime.runtimeconfig.json e altri non-Python files),
  hidden-import clr_loader.netfx
2026-06-09 12:22:04 +02:00
5 changed files with 62 additions and 2 deletions

No files matched your search

+8
View File
@@ -87,6 +87,14 @@ jobs:
- name: Build exe
run: python build_windows.py
- name: Unblock files (rimuovi MOTW pre-zip)
shell: pwsh
run: |
# Per ridurre l'incidenza del bug "Failed to resolve
# Python.Runtime.Loader.Initialize" causato da Mark of the Web.
Get-ChildItem -Path dist/MusicTools -Recurse -Include *.dll,*.exe,*.pyd `
| Unblock-File
- name: Package -> zip
shell: pwsh
run: |
+11
View File
@@ -106,6 +106,9 @@ def run_pyinstaller():
"--windowed",
"--onedir",
"--noconfirm",
# Forza rebuild pulita (senza, residui di build vecchi possono
# confondere il bundling di pythonnet/clr_loader).
"--clean",
]
if icon_path.exists():
cmd.extend(["--icon", str(icon_path)])
@@ -118,6 +121,9 @@ def run_pyinstaller():
"--hidden-import", "webview.platforms.winforms",
"--hidden-import", "clr",
"--hidden-import", "clr_loader",
"--hidden-import", "clr_loader.netfx",
"--hidden-import", "clr_loader.types",
"--hidden-import", "pythonnet",
"--hidden-import", "requests",
# Collegamenti completi: webview, pythonnet, clr_loader (porta
# con se Python.Runtime.dll + nethost.dll + runtimeconfig.json
@@ -127,6 +133,11 @@ def run_pyinstaller():
"--collect-all", "pythonnet",
"--collect-all", "clr_loader",
"--collect-all", "mutagen",
# collect-data prende anche i file .json/.dll non-Python che
# collect-all potrebbe saltare (Python.Runtime.runtimeconfig.json
# in particolare).
"--collect-data", "pythonnet",
"--collect-data", "clr_loader",
"--copy-metadata", "pythonnet",
"--copy-metadata", "clr_loader",
# Binari bundled
+1 -1
View File
@@ -5,7 +5,7 @@ import os
import sys
from pathlib import Path
VERSION = "v1.7.5"
VERSION = "v1.7.7"
APP_NAME = "MusicTools"
+40
View File
@@ -4,6 +4,46 @@ import os
import sys
from pathlib import Path
# Windows: forza il caricamento del runtime pythonnet PRIMA di importare
# webview. Con PyInstaller il lazy-loader fallisce con
# "Failed to resolve Python.Runtime.Loader.Initialize" perche'
# Python.Runtime.dll viene bundlata ma il loader non sa risolverla
# senza l'inizializzazione esplicita. Fix conferma:
# https://github.com/pythonnet/pythonnet/issues/2178
if sys.platform == "win32":
# ============================================================
# Fix Windows: rimuovi Mark of the Web (MOTW) dalle DLL bundled.
# Quando l'utente scarica il .zip dal browser, Windows aggiunge
# uno stream NTFS Zone.Identifier a TUTTI i file estratti.
# .NET Framework 4.x rifiuta silenziosamente di risolvere i
# symbol export degli assembly managed con MOTW -> il loader
# netfx di pythonnet fallisce con "Failed to resolve
# Python.Runtime.Loader.Initialize".
# Soluzione: cancelliamo lo stream :Zone.Identifier da ogni
# .dll/.exe del bundle al primo avvio (operazione idempotente
# e sicura: l'utente ha gia eseguito l'exe esplicitamente).
# Vedi: https://github.com/r0x0r/pywebview/issues/1215
# ============================================================
if getattr(sys, "frozen", False):
try:
import ctypes
_kernel32 = ctypes.windll.kernel32
_bundle = Path(sys._MEIPASS) # type: ignore[attr-defined]
for _f in _bundle.rglob("*"):
if _f.suffix.lower() in (".dll", ".exe", ".pyd"):
_kernel32.DeleteFileW(f"{_f}:Zone.Identifier")
except Exception as _e:
print(f"[bootstrap] MOTW cleanup failed: {_e}")
try:
if getattr(sys, "frozen", False):
os.environ["PYTHONNET_RUNTIME"] = "netfx"
from pythonnet import load as _pythonnet_load
_pythonnet_load("netfx")
import clr # noqa: F401 - inizializza il loader
except Exception as _e:
print(f"[bootstrap] preload pythonnet failed: {_e}")
import webview
from api.bridge import Api
+2 -1
View File
@@ -5,4 +5,5 @@ mutagen>=1.47.0
pyobjc-core>=10.0 ; sys_platform == "darwin"
pyobjc-framework-Cocoa>=10.0 ; sys_platform == "darwin"
pyobjc-framework-WebKit>=10.0 ; sys_platform == "darwin"
pythonnet==3.0.3 ; sys_platform == "win32"
pythonnet==3.0.5 ; sys_platform == "win32"
clr-loader==0.2.7.post0 ; sys_platform == "win32"